将子类添加到BaseClass向量C ++不起作用

时间:2018-03-16 14:44:47

标签: c++ c++11 vector c++14 subclass

我有以下问题,我有2个类FooClass和BaseClass,以及多个BaseClass子类。

我想将这些不同的子类添加到FooClass中的相同Vector中,因为我只是从baseclass实现函数,所以我可以通过向量键访问它们。

在下面的示例中,每个子类使用setName()设置BaseClass的字符串名称,并使用getName()返回它。 每个子类也使用BaseClass中定义的thisFunctionisforAll()。

代码编译正常,除非我添加vClasses.push_back(thesubclass); 所以我需要帮助我如何将所有这些BaseClass的子类放入同一个向量中。

我想迭代FooClass向量中的varius子类BaseClass来输出它们的名字。 示例在main.cpp

我认为如果我们共享基类并且向量是基类的类型,我可以向向量添加不同的子类。

以下是来源:

FooClass.h:

#ifndef TESTPROJECT_FOOCLASS_H
#define TESTPROJECT_FOOCLASS_H


#include <vector>
#include "BaseClass.h"

using namespace std;
class FooClass
{
private:
    vector<BaseClass> vClasses;
public:
    void addClassToVector(BaseClass &classToAdd);
    void getNames();
};


#endif //TESTPROJECT_FOOCLASS_H
    FooClass.cpp


    #include "FooClass.h"

    void FooClass::addClassToVector(BaseClass &thesubclass)
    {
        vClasses.push_back(thesubclass);
    }
    void FooClass::getNames()
    {
      for (size_t i; i < vClasses.size(); i++)
      {
        cout << vClasses[i].getName() << endl;
      }
    }
BaseClass.h


#ifndef TESTPROJECT_BASECLASS_H
#define TESTPROJECT_BASECLASS_H

#include <iostream>
using namespace std;
class BaseClass
{
protected:
    string name;

public:
    virtual void setName()= 0;
    virtual string getName()=0;
    void thisFunctionisforAll();
};


#endif //TESTPROJECT_BASECLASS_H
BaseClass.cpp

#include "BaseClass.h"

void BaseClass::thisFunctionisforAll() {
    cout << "Every subclass uses me without implementing me" << endl;
}
SubClass.h


#ifndef TESTPROJECT_SUBCLASS_H
#define TESTPROJECT_SUBCLASS_H


#include "BaseClass.h"

class SubClass : public BaseClass {
    virtual void setName();

    virtual string getName();

};


#endif //TESTPROJECT_SUBCLASS_H
SubClass.cpp

#include "SubClass.h"

void SubClass::setName()
{
    BaseClass::name = "Class1";
}

string SubClass::getName() {
    return BaseClass::name;
}
SubClass2.h
    #ifndef TESTPROJECT_SUBCLASS2_H
#define TESTPROJECT_SUBCLASS2_H


#include "BaseClass.h"

class SubClass2 : public BaseClass
{
    virtual void setName();

    virtual string getName();

};


#endif //TESTPROJECT_SUBCLASS2_H
SubClass2.cpp

#include "SubClass2.h"

void SubClass2::setName()
{
    BaseClass::name = "Class 2";
}

string SubClass2::getName() {
    return BaseClass::name;
}
main.cpp


#include "FooClass.h"

void FooClass::addClassToVector(BaseClass &thesubclass)
{
    vClasses.push_back(thesubclass);
}

void FooClass::getNames()
{
    for (size_t i; i < vClasses.size(); i++)
    {
        cout << vClasses[i].getName() << endl;
    }
}

我认为解决方案很简单,但我在PHP方面经验丰富,而且我没有遇到过这样的问题。

2 个答案:

答案 0 :(得分:2)

您需要使用指针或引用。当您使用指针时,多态性仅适用于C ++。除非您使用指针或引用,否则不能将子类视为超类。您需要std::vector<BaseClass*>才能拥有基类和子类的容器。

由于您是该语言的新手,我建议您研究指针的工作原理。

答案 1 :(得分:0)

像vector这样的容器直接包含东西,而不是对东西的引用(例如,Java中找不到 - 不确定PHP)。如果您有一个课程Foo,则std::vector<Foo>将包含Foo个实例。如果有一个类Bar 派生自Foo ,并且您将Bar放入此向量中,则只能获得Foo部分。其余部分被切断或切片,如下所述:C++ - What is object slicing?。这是它在C ++中的工作方式。

现在,您可以将指针放入向量中,例如vector<Foo*>。但是vector对象不会拥有指向的东西(例如,像Java这样的语言)。它只会持有指针。所以你必须分别管理对象的生命周期。这是C ++的一个主要特性。如果您希望向量拥有对象,则必须将指针作为特定类型的包装指针放在那里,通常是std::unique_ptrstd::shared_ptr

但现在你正在研究更复杂但绝对基本的C ++内容,你需要了解很多关于所有权和容器如何工作的内容。不过,有很多方法可以学习,我相信你知道,Stack Overflow的c++标签会对这些主题提出很多问题并为你提供有用的答案。