如何让一些派生类使用相同的方法,而另一些派生类则使用另一种方法

How to let some derived classes use the same method, and some other derived classes use another?

本文关键字:方法 派生 另一种      更新时间:2023-10-16

考虑以下继承层次结构:

class A{};
class X1:A{};
class X2:A{};
class Y1:X1{};
class Y2:X2{};
class Z1:X1{};
class Z2:X2{};

在X层中可能有更多的类,如类X3:A{}
每个X?类有两个派生类Y?和Z
我需要添加一个方法,即所有Y1…Yn实例都做相同的操作,所有Z1…Zn实例都使用另一个方法实现
这是一个非公共方法,由类a中的方法调用。
有没有一种优雅的方法来完成这项任务?

如果公共继承是可接受的,那么您可以定义父类,并在派生类中具有指向这些类的指针:

#include <iostream>
using namespace std;
class A
{
    // A cannot be abstract - it must be able to invoke a 
    // "non-public method" whose implementation varies based on Y vs Z
    public:
    virtual void myFun()=0;
    void callMyFun(){myFun();}
};
class Y
{
public:
    void myFun(){cout<< "myFun from Y superclass" << endl;}
};
class Z
{
public:
    void myFun(){cout<< "myFun from Z superclass" << endl;}
};
class X1:public A{};
class X2:public A{};
class Y1:X1{
    Y* y;
    void myFun(){y->myFun();}
};
class Y2:public X2{
    Y* y;
    void myFun(){y->myFun();}
};
class Z1:public X1{
    Z* z;
    void myFun(){z->myFun();}
};
class Z2:public X2{
    Z* z;
    void myFun(){z->myFun();}
};
int main()
{
    Y2 myY2;
    myY2.callMyFun(); // myFun from Y superclass
}

委派模式可能会回答问题

这个例子是上面复杂Java例子的C++版本。由于C++没有接口构造,所以纯虚拟类也扮演着同样的角色。优点和缺点在很大程度上与Java示例相同。

#include <iostream>
using namespace std;
class I {
  public:
    virtual void f() = 0;
    virtual void g() = 0;
    virtual ~I() {}
};
class A : public I {
  public:
    void f() { cout << "A: doing f()" << endl; }
    void g() { cout << "A: doing g()" << endl; }
    ~A() { cout << "A: cleaning up." << endl; }
};
class B : public I {
  public:
    void f() { cout << "B: doing f()" << endl; }
    void g() { cout << "B: doing g()" << endl; }
    ~B() { cout << "B: cleaning up." << endl; }
};
class C : public I {
  public:
    // construction/destruction
    C() : i( new A() ) { }
    virtual ~C() { delete i; }
  private:
    // delegation
    I* i;
  public:
    void f() { i->f(); }
    void g() { i->g(); }
    // normal attributes
    void toA() { delete i; i = new A(); }
    void toB() { delete i; i = new B(); }
};
int main() {
    C c;
    c.f();   //A: doing f()
    c.g();   //A: doing g()
    c.toB(); //A: cleaning up.
    c.f();   //B: doing f()
    c.g();   //B: doing g()
}

您可能需要了解PIMPL习语。函数实现封装在一个类中,您的Y*s和Z*s将委托给该类。