动态绑定shared_ptr

时间:2018-11-27 08:59:20

标签: c++ pointers dynamic decorator shared-ptr

我正在尝试遵循装饰器模式来实现某些功能,但似乎无法从shared_ptr中获得可以通过普通指针获得的相同运行时行为。 我有一个带有虚拟方法的基本类 I (接口),然后从中派生了两个类:

  • class A (组件),其中将包含一些数据
  • I 派生的
  • class B (装饰器),还包含指向它的指针并将实现一些其他的行为。我有一个构造函数,用于初始化指向特定 I (或派生)对象的指针。

然后我希望能够建立一个 B 对象,其指针指向 A ,这样,当我调用通用方法时,我会调用 A 而不是 I

如果我以通常的方式在 B 中创建指针,则可以执行此操作(在代码示例中,请参见类 B_basic 和主对象 bb )。

但是,如果我将此指针设置为 I shared_ptr ,它将从 I ,即使我将其指向实际的 A (在代码中,请参见 B_shared 类和对象 bs

class I {

   public:
      virtual void method() {cout<<"I\n";}
      virtual ~I() = default;
};

class A : public I {
   public:
      virtual void method() {cout<<"A\n";}
};

class B_shared : public I {
   public:
      shared_ptr<I> shared_pointer;
      B_shared(const I& i) : shared_pointer(make_shared<I>(i)) {}
      virtual void method() { 
         cout<<"B_shared > ";

         shared_pointer->method();
      }
};

class B_basic : public I {
   public:
      I* basic_pointer;
      B_basic(I* i) : basic_pointer(i) {}
      virtual void method() { 
         cout<<"B_basic > ";

         basic_pointer->method();
      }
};


int main() { 
   A a;
   B_shared bs(a);
   B_basic bb(&a);
   bs.method(); // B_shared > I
   bb.method(); // B_basic > A
}

我在做什么错了?

1 个答案:

答案 0 :(得分:2)

这是对象切片。

在下面的行中,您将复制类型为i的实例A到类型I的副本。因此,原始类型A被切片为基本类型I

shared_pointer(make_shared<I>(i)) 

在原始指针版本basic_pointer(i)中,您保存了指针本身,不进行切片。