我有以下问题,我有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方面经验丰富,而且我没有遇到过这样的问题。
答案 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_ptr
或std::shared_ptr
。
但现在你正在研究更复杂但绝对基本的C ++内容,你需要了解很多关于所有权和容器如何工作的内容。不过,有很多方法可以学习,我相信你知道,Stack Overflow的c++
标签会对这些主题提出很多问题并为你提供有用的答案。