【问题标题】:How can two derived objects of same base class communicate?同一基类的两个派生对象如何通信?
【发布时间】:2012-06-06 18:37:59
【问题描述】:

我有以下情况

class B {
public:
    B() {};
    virtual ~B() {};
    virtual void seti( int x ) { i = x; };
    virtual void setj( int x ) { j = x; };
    virtual void add() =0;

protected:
    int i;
    int j;
};
class D :  public B {
public:
 virtual void add() { cout << "D-add:" << i + j << endl; }; 
};

class E: public B {
public:
    void seti( int x ) { i = x; };
    void add() { cout << "E-add:" << i + j << endl; }; 
    void mult() { cout << "E-mult:" << i * j << endl; }; 
};

int _tmain(int argc, _TCHAR* argv[])
{
    D *d = new D();
    d->seti(4); d->setj(5); d->add();
    E*e = d;
    e->seti(8); e->add(); e->mult();
    return 0;
}
我收到以下错误 1>.\CallBack.cpp(38):错误 C2440:“正在初始化”:无法从“D *”转换为“E *” 1> 指向的类型不相关;转换需要 reinterpret_cast、C-style cast 或 function-styl`在此处输入代码`e cast

我想要做的是当我实例化 E 时,我使用了 D 的所有信息/成员并用它做更多的事情。我应该像上面那样使用分层继承还是应该使用多级继承,或者还有其他更好的方法。请指教。谢谢!

【问题讨论】:

标签: c++ design-patterns derived-class


【解决方案1】:

你可以改变

class E: public B {

class E: public D {

【讨论】:

    【解决方案2】:

    我认为你想要的是一个“转换 ctor”——E 上的构造函数,它将指向 D 的引用/指针作为参数并根据 D 的值填充自身。要复制 B 上定义的字段,您可以这样做:

    class B {
    public:
    ....
      B(B& source) { this->i = source.i; this->j = source.j; }
    ....
    }
    class E {
    public:
    ....
      E(D& source) : B(source) { // no need to do anything about i,j
      }
    ....
    }
    

    此外,您可以编写一个转换器类 (DtoEConverter),它具有执行此操作的功能。

    【讨论】:

    • 同意转换构造函数是一种方法......但这将迫使我编写一些函数,如“int getj(){return j;}”。除了不写任何“get”函数还有什么办法?
    • 当然有...在B上定义一个“copy ctor”,然后从E上的转换ctor调用它。在B的copy ctor中,你的i和j可以直接复制,没有 get 函数。
    • 你能给我一个示例代码吗?将不胜感激...谢谢您的回复
    【解决方案3】:
    D *d = new D();
    d->seti(4); d->setj(5); d->add();
    E*e = d;
    

    d 是指向D 的指针。您不能将指向 D 的指针分配给接受指向 E 的指针的变量,因为类型不直接相关。

    它们在基类中相关,但d 不是E,这就是您遇到的问题。

    你可以这样做:

    B* e = d;
    

    因为d B

    顺便问一下,你的问题标题是:

    两个同一个基类的派生对象如何通信?

    强调我的。你没有两个派生对象——你只有一个。有两个类,但您只能在此处实例化一个实际对象:

     D *d = new D();
    

    【讨论】:

    • 谢谢!我对上面的代码做了一点更新。我想使用保存在“d”中的所有数据并执行另一个操作(比如上面编辑的代码中的乘法)。
    【解决方案4】:

    不过,我不是 C++ 程序员,但我希望尝试根据我们在 C sharp 中可能做的事情提供替代方案

    您可能会向 D 类添加接口....比如接口 IAdd,然后将 D 类传递给 E 类。

    所以在 E 类的构造函数中,你可以有类似:public E(Interface x) .... 传入 D 类而不是 X。

    如果这有帮助,请告诉我:)

    问候

    【讨论】:

      【解决方案5】:

      与其用班级间的交流来污染你的主要班级,不如引入一个新班级。

      class DECommunicator
      {
      public:
        DECommunicator(D* dPtr, E* ePtr)
        {
          mDPtr = dPtr;
          mEPtr = ePtr;
        }
      
        void DSetI(int x)
        {
          mDPtr->setI(x);
        }
      
        // add additional methods to allow D to "talk" to E and vice versa
      
      private:
        D* mDPtr;
        E* mEPtr;
      }
      

      很难给出代码,因为我不太确定你想要实现什么,给出你的例子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        • 2022-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-12
        相关资源
        最近更新 更多