【问题标题】:Every abstract classes knows others每个抽象类都认识其他类
【发布时间】:2017-06-16 23:51:17
【问题描述】:

我很难用文字清楚地表达我的想法。下面的例子可以解释我的想法。我有两个抽象类和两个派生类,

class Base1{
        public:
        virtual void f1() = 0;
        std::string get(){ return "HelloWorld";}
};

class Derived1: public Base1{
        public:
        void f1() {}
        void update (std::string& update){
            **should call like**  Base2::Derived2::update_data(this);}
};

=> 和

class Base2{
        public:
        virtual void f2 () = 0;
};

class Derived2: public Base2{
        public:
        void f2() {}
        void get (Base1& d1){ d1.Base1::get (); }
        void update_data (Base1& d1){ d1.Base1::get (); }
};

=> 类被称为

int main(){
Derived1 d1;  
Derived2 d2;  

d2.get (d1);  
std::string hi = "hiWorld";
d1.update (hi);
return 0;
}

如何在不传递d1.update () 中的Base2 实例的情况下实现**should call like**

另一个问题是,当每个类对象知道其他对象时,它叫什么?

谢谢。

【问题讨论】:

  • Derived1 需要Derived2 实例的可见性。假设该实例由名为thing 的变量(或数据成员)表示,它可以执行thing.update_data(*this)。这显然依赖于类 Derived2 在调用点(以及创建 thing 时)对编译器可见的定义
  • 在这种情况下,您希望 Derived1::update() 如何知道要在哪个 Derived2 对象实例上调用 update_data()?
  • 您可能应该阅读有关类和对象(或类的实例)之间的差异。它将帮助您了解如何实现您想要的。我还建议您阅读观察者模式,因为这可能是您想要实现的目标。

标签: c++ inheritance abstract-class


【解决方案1】:

您似乎需要一种称为double-dispatch 的技术。 C++ 只直接支持single-dispatch - 你得到的行为只基于单个实例。

   a->virtualFunction( params );  // exactly which implementation is called depends on the concrete type of a.

对于双重调度(不存在),您需要类似

  (a,b)->virtualFunction( params );  // where the call is based on both parameters.

这个问题有一些解决方案。这些需要工作,其中一种类型需要另一种类型的知识,但只能这样。

考虑一组我们要在表面上绘制的几何形状。 类表面; 类可绘制{ 上市: 虚拟 ~Drawable () {} 虚空绘制(表面*)= 0; };

   class Surface {
     public:
        virtual ~Surface () {}
   // details ommitted.
   }

   class Rectangle : public Drawable {
   };
   class Circle : public Drawable {
   }

   // and some surfaces

   class PrinterSurface : public Surface {
   };

   class PlotterSurface : public Surface {
   };

我们实际要调用的代码,取决于表面和形状。

为了解决这个问题,我们选择最有界的层次结构之一,并告诉另一个层次结构该类型的具体实例。

在这个例子中,我们认为比渲染它们的技术更多的形状和可绘制对象存在。

所以每个可绘制项都知道如何在每个表面上绘制。

   class Drawable {
     public:
        virtual ~Drawable () {}
        virtual void drawPrinter( Surface * ) = 0;
        virtual void drawPlotter( Surface * ) = 0;
        virtual void drawSurface( Surface * ) = 0;
   };

   class Surface {
     public:
        virtual ~Surface () {}
        virtual void draw( Drawable * pDrawable ) = 0;
   }

   class PrinterSurface : public Surface { 
      void draw( Drawable * pDrawable ) {
           pDrawable->drawPrinter( this );
      }

   };

现在对Surface->draw( Drawable *) 的调用将被反弹到一个具体的实现中,其中每个Drawable 都知道如何在设备上渲染,但设备不知道Drawables 的范围

进一步阅读:wikipedia : double dispatch 以获得更完整的描述。

我会推荐设计模式书wikipedia : design patterns

设计模式提供了一些设计词汇的概念,使提出这种形式的问题变得更加容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多