我试图用这个简单的例子来理解C ++中的多态性机制(为了清楚起见,构造函数在hpp文件中明确写出,同样适用于公共成员)
基类:
//Base.hpp
#ifndef _Base_H_
#define _Base_H_
class Base{
public:
int BaseVar;
Base():BaseVar(0){};
int getBaseVar(){return BaseVar;}
virtual int DoNothing(){return 0;};
};
#endif
派生类
//Derived.hpp
#include "Base.hpp"
#ifndef _Derived_H_
#define _Derived_H_
class Derived: public Base{
public:
int DerivedVar;
Derived():Base(),DerivedVar(0){};
int getDerivedVar(){return DerivedVar;}
};
#endif
Polymorph class
//Polymorph.hpp
#include "Derived.hpp"
#include <vector>
using namespace std;
#ifndef _Polymorph_H_
#define _Polymorph_H_
class Polymorph{
public:
vector<Base *> PolyMorphVector;
Polymorph(int VectorSize):PolyMorphVector(VectorSize)
{
for (int i(0);i<VectorSize;i++)
PolyMorphVector[i]=new Derived;
}
};
#endif
主程序
//main.cpp
#include "Polymorph.hpp"
int main()
{
int i;
Polymorph *MyPolymorph = new Polymorph(10);
i=MyPolymorph->PolyMorphVector[0]->getDerivedVar();//copmiler error: "'getDerivedVar' : is not a member of 'Base'" ... Oh, really?
i=(dynamic_cast<Derived *>(MyPolymorph->PolyMorphVector[0]))->getDerivedVar();//OK!!
return 0;
}
使用Win7 OS(64位)在VS 2010中编译了Everthing。
是作业:
PolyMorphVector[i]=new Derived;
被视为良好做法?
为什么我必须明确地使用dynamic_cast,尽管我使用Derived类分配了PolyMorphVector的每个元素?
答案 0 :(得分:4)
(1)作业有效,但在任何地方都没有明确的所有权,你最好用
这样的东西std::vector<std::unique_ptr<Base>> poly_morph_vector;
然后按
初始化for (auto& b : poly_morph_vector) {
b = std::make_unique<Derived>();
}
(2)Base
没有该名称的成员函数,因此您得到编译时错误。如果你想要动态发送,你需要像
class Base {
public:
virtual int get_var() const { return base_var; }
};
class Derived : public Base {
public:
int get_var() const override { return derived_var; }
};
然后你的代码得到变量
auto i = MyPolymorph->poly_morph_vector.front()->get_var();
答案 1 :(得分:2)
您的示例中没有使用任何真正的多态性。多态的概念是可以从基类定义的接口调用派生类提供的函数。特别是,可以使用接口(调用virtual
方法)并完全独立地实现(定义派生类),但它可以工作。
struct base
{
virtual int method1() const = 0; // pure virtual: has to be overriden
virtual int method2(int i) const // defaults to base::method2()
{ return i*x; }
base(int i) : x(i) {}
virtual ~base() {} // derived can be destroyed from here
const int x;
};
void print(const base*p) // using the interface
{
std::cout << p->method1() << std::endl;
}
struct derived : base // providing an interface
{
int method1() const override
{ return method2(x); } // polymorphic call of foo::method2
derived(int i): base(i), x(i+i) {}
const int x;
};
struct foo : derived // extending the interface again
{
int method2(int i) const override
{ return i<<2; }
foo(int i) : derived(2+i);
};
std::vector<unique_ptr<base>> pter;
for(int i=0; i!=10; ++i)
pter.push_back(make_unique<foo>(i)); // unfortunately make_unique is C++14
for(auto const&p:pter)
print(p.get()); // calls foo::method1()
请注意pter
的析构函数将调用base::~base()
,virtual
将调用foo
的析构函数(尽管在此示例中,它不执行任何操作)。