如何让一个向量接受具有相同基类的 2 个不同的类?

Posted

技术标签:

【中文标题】如何让一个向量接受具有相同基类的 2 个不同的类?【英文标题】:How do I get a vector to take in 2 different classes with the same base class? 【发布时间】:2015-02-09 00:20:45 【问题描述】:

我知道在 C# 中有一种方法可以让变量接受值,只要它们共享一个基类,但我对 C++ 感到困惑。我正在尝试做的事情可能吗?

这是我的代码的样子:

class BaseClass

    public:
        virtual void Setup() = 0;       
        virtual void DisplayText() = 0;
;

class A: public BaseClass

    public:     
        void Setup();       
        void DisplayText();
;

class B: public BaseClass

    public:     
        void Setup();       
        void DisplayText();
;


//main.cpp

A a;
B b;

std::vector<BaseClass> vector = std::vector();

void main()

    vector.push_back(a);
    vector.push_back(b);

    for_each (vector.begin(), vector.end(), vector.Setup());

    return 0;

就我现在所拥有的,虽然当我尝试运行它时它给了我这个错误:

IntelliSense: no instance of overloaded function
"std::vector<_Ty,_Alloc>::push_back [with _Ty=BaseClass,,Alloc=std::allocator<BaseClass>]"
matches the argument list
argument types are: (A*)
object type is: std::vector<BaseClass, std::allocator<BaseClass>>

【问题讨论】:

我不确定它是否可行,但请尝试创建智能指针而不是原始对象,并将它们推送到向量中。 在C++中,void main()不是标准的,应该改成int main()。 @adam10603 什么是智能指针? Google 是你的朋友 【参考方案1】:

这里有很多错误。第一:

std::vector<BaseClass> vector = std::vector();

这是无效的语法,vector 不是一种类型,因此您不能像在右侧那样创建一个。这样就足够了:

std::vector<BaseClass> vector;

第二,这不是你称呼for_each的方式:

for_each (vector.begin(), vector.end(), vector.Setup());

vector 上没有 Setup() 函数。如果有的话,那甚至不是你想打电话的Setup。你要使用的是std::mem_fun

for_each (vector.begin(), vector.end(), std::mem_fn(&BaseClass::Setup));

一旦我们到达那里,我们就会遇到代码中的主要问题:您是slicing 您的所有对象!好吧,首先,我们试图将抽象类按值存储在vector 中,这是不可能的。如果是这样,由于切片问题,它无论如何都不会做你想做的事。您需要做的是更改您的 vector 以存储指向 BaseClass 的指针:

std::vector<BaseClass*> vector;
vector.push_back(&a);
vector.push_back(&b);

然后,只有这样,您的代码才会编译。好吧,假设您在某处为您的虚拟覆盖提供定义 - 否则它不会链接。

【讨论】:

是否可以对向量的类型名使用引用? @Mark 你的意思是vector&lt;BaseClass&amp;&gt;?不,元素类型必须是可分配的。 @Barry 我已经实现了你写的大部分内容。不过我需要做出改变。我想将基类中的向量作为静态值,我需要在我的主类中调用它。但问题是它给了我这个链接器错误:错误LNK2001:未解析的外部符号“public:静态类std::vector > BaseClass::vector”(? s_Screens@GameScreens@@2V?$vector@PAVGameScreens@@V?$allocator@PAVGameScreens@@@std@@@std@@A) 我该如何解决? @SyntaxIsEvil What is an unresolved external symbol error? @Barry 我忘了在我的主目录中初始化我的向量。这一切都完美无缺。非常感谢您的帮助!【参考方案2】:

是的,这是可行的。您需要更改您的向量以保存BaseClass* 指针。

std::vector<BaseClass*> vector;

vector.push_back(&a);
vector.push_back(&b);

void DoSetup(BaseClass *obj)

    obj->Setup();


for_each (vector.begin(), vector.end(), DoSetup);

【讨论】:

【参考方案3】:
    删除= std::vector();没必要 请将该初始化代码 A a; B b; std::.... 移动到 main 函数中。 您的for_each 也是错误的。 如果sizeof(BaseClass) 为零,我不知道 C++ 会做什么。

我认为你隐藏了太多代码:GameScreens 是什么?

【讨论】:

sizeof(BaseClass) 不为零。 我不知道 for_Each 在 c++ 中是如何工作的。我只是把它作为我想要它做的一个例子快速扔进去。 GameScreens 只是 BaseClass。我错过了电话 您可以保存 boost::function&lt;void()&gt; 对象,而不是根本不需要基类。

以上是关于如何让一个向量接受具有相同基类的 2 个不同的类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在向量中存储多个类的不同对象?

具有相同名称的类的构造函数继承

从基类类型的向量访问派生类方法

matlab如何写一个类

jpa 2.0 对具有 2 个 ID 的类的注释,指向两个不同的表

继承与此类相同的基类的类的继承