我有两个班,每个班都有几个孩子:
class ContainerGeneral {...};
class ContainerTypeA : ContainerGeneral {
public:
void doSomethingA();
};
class ContainerTypeB : ContainerGeneral {
void doSomethingB();
};
class InterpreterGeneral {
protected:
ContainerGeneral* container;
};
class InterpreterTypeA : InterpreterGeneral {
public:
void saveContainer(ContainerTypeA* cont) {
container = cont;
}
};
class InterpreterTypeB : InterpreterGeneral {
public:
void saveContainer(ContainerTypeB* cont) {
container = cont;
}
};
Interpreter
类用于相应类型的容器(A
至A
,B
至B
,General
至{ {1}})。为此,我向General
对象添加了一个指向InterpreterGeneral
对象的成员指针。我希望ContainerGeneral
将此对象作为InterpreterGeneral
来寻址,但我希望继承的类将能够寻址与适当类型的容器相同的容器。我可以通过在寻址时继承继承类的指针来做到这一点(仅示例ContainerGeneral
以节省空间)
A
或者通过添加一个继承类型的新成员指针来指向与容器相同的位置:
(ContainerTypeA*)container->doSomethingA();
在这种情况下,最佳实践是什么?有没有一种方法可以做到尽可能干净,而不必每次都进行转换,并且不添加不包含任何“新”信息的新成员?
答案 0 :(得分:0)
如果您需要有关InterpreterTypeA
和InterpreterTypeB
中的容器实例的具体类型信息,请通过不在代码GeneralContainer*
中存储GeneralInterpreter
数据成员来在代码中表达这一点({ {1}}数据成员在任何情况下都是值得商bat的),而是子类protected
和ContainerTypeA*
中具体的ContainerTypeB*
和InterpreterTypeA
数据成员。存储基类指针,然后通过强制转换来规避其限制,这掩盖了需要具体类型信息的事实。
此外,在容器基类中提供InterpreterTypeB
和doSomethingA()
的空默认实现,或者将它们转换为doSomethingB()
纯成员函数并将空移实现到virtual
和ContainerTypeA
中。然后,只需调用它们就很安全-当它是不需要的具体类型时,它们将不会做任何事情。
最后一个学究的侧面说明:我看不出有任何理由在层次结构中将派生类称为“ son”类。常用术语是“孩子”类。
答案 1 :(得分:0)
您要处理的问题具有virtual functions形式的解决方案。试试这个:
class ContainerGeneral {
public:
virtual void doSomething() = 0;
};
class ContainerTypeA : public ContainerGeneral {
public:
void doSomething() {
std::cout << "Hello A!" << std::endl;
};
};
class ContainerTypeB : public ContainerGeneral {
public:
void doSomething() {
std::cout << "Hello B!" << std::endl;
};
};
因此,您完全不必担心从InterpreterGeneral
继承:
class InterpreterGeneral {
public:
void doSomething()
{
container->doSomething();
}
private:
ContainerGeneral* container;
};
旁注:当然,这会产生一些运行时开销。如果您在运行时不需要多态,则可以避免这种情况。看看the static polymorphism。仅当您是忍者。