std::shared_ptr 的 std::vector 可以保存指向同一基类的不同子类的指针吗? [已关闭]

问题描述 投票:0回答:3

我一直在尝试创建一个动态数据结构来保存许多不同类的对象,所有这些对象都派生自同一个基类。 我在很多地方都找到了建议,可以使用共享指针向量来完成此操作。但是我无法让它发挥作用。 代码如下:

class ElementDetail
{
public:
    virtual void* getData() = 0;

};

class TypecodeDetail : ElementDetail
{
public:
    TypecodeDetail(uint32_t typecode) : _typeCode(typecode) {}

    void* getData();

private:
    uint32_t _typeCode{};
};

int main()
{
    std::vector<std::shared_ptr<ElementDetail>> details;
    details.push_back(std::make_shared<TypecodeDetail>());
}

这会在push_back上产生错误:

错误(活动)E0304 没有重载函数的实例与 参数列表 参数类型有:

(std::shared_ptr<TypecodeDetail>)
对象类型是:
std::vector<std::shared_ptr<ElementDetail>, std::allocator<std::shared_ptr<ElementDetail>>>

我已经从我搜索的许多类似问题的答案中复制了这段代码,但它不起作用。谁能告诉我为什么?我正在尝试的可能吗?

c++ inheritance stdvector
3个回答
4
投票

有几个问题:

  1. 您需要public继承(通过不告诉编译器任何内容,将使用private继承)
  2. 您可以通过调用
    TypecodeDetail
    来调用
    std::make_shared<TypecodeDetail>()
    的默认构造函数。但是,当您定义一个采用整数的构造函数时,编译器不再生成默认构造函数。因此,要么使用整数值调用构造函数,要么必须定义默认构造函数(例如使用
    TypecodeDetail() = default;
#include <cstdint>
#include <vector>
#include <memory>

class ElementDetail
{
public:
    virtual void* getData() = 0;

};

class TypecodeDetail : public ElementDetail
{
public:
    TypecodeDetail(uint32_t typecode) : _typeCode(typecode) {}

    void* getData() { return nullptr; } 

private:
    uint32_t _typeCode{};
};

int main()
{
    std::vector<std::shared_ptr<ElementDetail>> details;
    details.push_back(std::make_shared<TypecodeDetail>(35));
}

回答这个问题:是的,这是可能的(建议不要使用 new/delete)


2
投票

智能指针几乎在所有方面都模仿实际指针。包括通过指向基类的指针处理多态性。

所以回答你的问题:是的,那会起作用。

您收到的错误是因为您尝试默认构造一个

TypecodeDetail
对象,该对象没有默认构造函数。您需要传递
TypecodeDetail
构造函数所需的参数:

details.push_back(std::make_shared<TypecodeDetail>(123));  // For example

还有其他问题,正如评论中提到的。私人继承是主要的。


0
投票

已在评论中解决。如果其他人遇到困难,问题是类继承默认是私有的,需要显式公开。所以在这种情况下:

class TypecodeDetail : ElementDetail

应该是

class TypecodeDetail : public ElementDetail
© www.soinside.com 2019 - 2024. All rights reserved.