需求:将一系列操作步骤放在链表中按需调用。
我将每个操作步骤用一个类实现,将各类继承于一个基类,再将指向各子类的基类指针放在QVector/Vector,即可通过C++的多态实现调用各子类。
为此,我写了俩个范例测试代码.
一,各子类只单一继承同一基类
#include <iostream>
#include <vector>
using namespace std;
#include <QDebug>
class Base
{
public:
virtual ~Base() {}
virtual void printName();
};
void Base::printName()
{}
class Derived0 : public Base
{
public:
~Derived0();
void printName();
};
Derived0::~Derived0()
{}
void Derived0::printName()
{
qDebug() << "I am derived 0";
}
class Derived1 : public Base
{
public:
~Derived1();
void printName();
};
Derived1::~Derived1()
{}
void Derived1::printName()
{
qDebug() << "I am derived 1";
}
int main()
{
QVector<Base*> classVector;
Base* ptrDerived0 = new Derived0;
classVector.push_back(ptrDerived0);
Base* ptrDerived1 = new Derived1;
classVector.push_back(ptrDerived1);
QVector<Base*>::iterator end = classVector.end();
for (QVector<Base*>::iterator it = classVector.begin(); it != end; ++it) {
(*it)->printName();
}
system("pause");
return 0;
}
注意点:
基类Base, 虽简单,注意点还不少,如下错误:
class Base //这样将出现两个警告错误
{ //1,“Base" has virtual functions but non-virtual destructor Base有虚函数,却用了非虚析构函数
public: //2,Base‘ has no out-of-line virtual method definitions;its vtable will be emitted in every translation unit.
virtual void printName() = 0; //base没有类外部虚方法定义,它的虚方法表会给每个翻译单元发送消息
};
1,任何有一个虚拟方法及打算使用多态方法的C++基类,都必须包含一个虚析构函数。这有助于确保当利用基类的指针访问子类(多态)时,可调用子类的析构函数,避免内存泄露。可是,出现这种常见的C++编译错误时,大多数C++编译器并没有警示信息。感谢QT 的警示信息!
因此,加上 virtual ~Base() {}
2,网摘: If a class is defined in a header file and has a vtable (either it has virtual methods or it derives from classes with virtual methods), it must always have at least one out-of-line virtual method in the class. Without this, the compiler will copy the vtable and RTTI into every .o file that #includes the header, bloating .o file sizes and increasing link times
译:如果一个类在头文件中定义,并且有一个虚方法表(不管是虚方法还是继承基类的虚方法),那么该类必须至少将一个虚方法定义在类定义外部。否则,编译器将会复制虚表和RTTI给每一个包含该头文件的目标.o文件,折将膨涨.o文件的大小,增加编译连接时间。
因此,将纯虚函数声明在类内部:virtual void printName();
在类定义外部:viod Base::printName(){}
后面就是两个子类Derived0,Derived1继承Base,并将指向他们的Base指针加入Vector了。
运行结果是正常的
I am derived 0
I am derived 1
二 各基类除了继承这个统一基类以外,还继承别的类。 多继承,因为我各个步骤类还都继承别的类,如QDialog等等
#include <iostream>
#include <vector>
using namespace std;
#include <QDebug>
enum classType{BaseType,Derived0Type,Derived1Type};
class Base
{
public:
virtual ~Base() {}
virtual void printName() = 0;
virtual classType myTypeNum();
};
classType Base::myTypeNum()
{
return BaseType;
}
class Base1
{
public:
void printBelong();
};
void Base1::printBelong()
{
qDebug() << "I derived from Base1 too!";
}
class Derived0 : public Base, public Base1
{
public:
~Derived0();
classType myTypeNum();
void printName();
};
Derived0::~Derived0()
{}
classType Derived0::myTypeNum()
{
return Derived0Type;
}
void Derived0::printName()
{
qDebug() << "I am derived 0";
}
class Derived1 : public Base, public Base1
{
public:
~Derived1();
classType myTypeNum();
void printName();
};
Derived1::~Derived1()
{}
classType Derived1::myTypeNum()
{
return Derived1Type;
}
void Derived1::printName()
{
qDebug() << "I am derived 1";
}
int main()
{
QVector<Base*> classVector;
Base* ptrDerived0 = new Derived0;
classVector.push_back(ptrDerived0);
Base* ptrDerived1 = new Derived1;
classVector.push_back(ptrDerived1);
QVector<Base*>::iterator end = classVector.end();
for (QVector<Base*>::iterator it = classVector.begin(); it != end; ++it) {
if((*it)->myTypeNum() == Derived0Type)
{
dynamic_cast<Derived0*>((*it))->printName();
dynamic_cast<Derived0*>((*it))->printBelong();
}
else if((*it)->myTypeNum() == Derived1Type){
dynamic_cast<Derived1*>((*it))->printName();
dynamic_cast<Derived1*>((*it))->printBelong();
}
}
system("pause");
return 0;
}
这里,我设计了一个专门定义各类返回类型的枚举类型enum classType{BaseType,Derived0Type,Derived1Type};
基类Base中设计为虚方法,返回BaseType;Derived0返回Derived0Type;Derived1返回Derived1Type。
子类除了继承Base以外,还继承Base1.
那么为了子类能正常调用不同基类的虚方法,要将Vector中统一的Base指针转换为自己的指针,这里就需要上面classType帮助判断了。如
if((*it)->myTypeNum() == Derived0Type)
{
dynamic_cast<Derived0*>((*it))->printName();
dynamic_cast<Derived0*>((*it))->printBelong();
}
运行结果也是如我所愿的
I am derived 0
I derived from Base1 too!
I am derived 1
I derived from Base1 too!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)