智能指针是否可以进行切片?

时间:2009-10-08 23:12:18

标签: c++ pointers smart-pointers object-slicing

如果我理解切片正确,我不认为这可能发生在指针或智能指针上。例如,如果你有:

class A
{
int something;
};

class B : public A
{
int stuff;
int morestuff;
};

int main()
{
    std::shared_ptr<B> b(new B());
    std::shared_ptr<A> a;
    a = b;
}

我的理解是,分配给“b”指向的对象的内存块仍然相同,并且在分配给智能指针“a”时不会改变。

请确认或拒绝我的理解,或让我知道与此相关的任何陷阱。

2 个答案:

答案 0 :(得分:6)

智能指针仍然是指针,因此这样的赋值不会导致切片。切片仅在处理值时发生,而不是指针。但是请注意,模板不知道点的项之间的关系,因此即使B派生自A,shared_pointer<B>也不是从shared_pointer<A>派生的,因此赋值不是(自动)使用原生指针获得自动上传。

编辑:详细说明最后一点。

切片发生的是值,而不是指针,所以(根据你对A和B的定义),如:

a ax = b;

可以工作,但会“切片”B对象成为A对象。但是,如果您拥有某种包含该项目实例的模板:

template <class T>
class holder { 
   T t_;
public:
   holder &operator=(T const &t) { 
       t_ = t;
       return *this;
   }
   holder &operator=(holder const &t) { t_ = t; return *this; }
};

现在,如果我们尝试将一个值分配给另一个,就像会导致切片一样:

holder<A> ha;
holder<B> hb;

A a;
B b;

ha = a;
hb = b;
ha = hb;

我们不会切片。相反,编译器只会给我们一个错误,告诉我们holder<A>holder<B>不是相关类型,所以分配不会发生 - 如果不添加显式强制转换,它根本就不会编译。

答案 1 :(得分:2)

你是对的,但它们不一样:你无法评价a->stuff