我正在尝试遵循装饰器模式来实现某些功能,但似乎无法从shared_ptr中获得可以通过普通指针获得的相同运行时行为。 我有一个带有虚拟方法的基本类 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
}
我在做什么错了?
答案 0 :(得分:2)
这是对象切片。
在下面的行中,您将复制类型为i
的实例A
到类型I
的副本。因此,原始类型A
被切片为基本类型I
。
shared_pointer(make_shared<I>(i))
在原始指针版本basic_pointer(i)
中,您保存了指针本身,不进行切片。