我有一个基类Base,还有几个派生类:Derived1,Derived2和Derived3。

我希望所有函数都具有funcOne,因此我可以像这样定期访问它:

Base* d1 = new Derived1();
Base* d2 = new Derived2();
Base* d3 = new Derived3();

d1->funcOne();
d2->funcOne();
d3->funcOne();

但是我只想在Derived1类中使用function funcTwo。
问题是,我想这样访问它:
d1->funcTwo();

除了在基类中创建带有某种实现的虚拟funcTwo之外,还可以通过其他方式实现此功能吗,例如
void funcTwo(){ cout << "There is no funcTwo for this class" << endl; }

还有其他仅适用于Derived1类的实现吗?

谢谢!

最佳答案

您可以想到两个主要选择。

您可以在问题中概述的基类中实现虚拟funcTwo。这通常是不好的做法,因为在Base,Derived2和Derived3的上下文中,funcTwo可能没有意义。最好是不对API进行滥用而不是编译,而不是仅仅抛出错误,或者更糟糕的是,静默地失败。
看起来像:

class Base() {virtual void funcTwo() {throw runtime_error("This should not be called");};
Base *d1 = new Derived1;
Base *d2 = new Derived2;
d1->funcTwo(); //fine
d2->funcTwo(); //compiles even though it doesn't make semantic sense, throws an exception

或者,您可以仅在Derived1中实现funcTwo。然后,您将尝试在可能的情况下直接保持指向Derived1的指针,并在不可能的情况下使用dynamic_cast。这是可取的,因为对Base::funcTwo的直接调用将无法编译,并且您的语义与实际尝试表达的内容更接近。
Base *b = new Derived1;
Derived1 *d1 = new Derived1;
Base *d2 = new Derived2;
d1->funcTwo(); //fine
if ((d1 = dynamic_cast<Derived1*>(b)) d1->funcTwo(); //fine
if ((d1 = dynamic_cast<Derived1*>(d2)) d1->funcTwo(); //funcTwo is not called, no errors
b->funcTwo(); //fails to compile

07-24 19:08