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

Posted

技术标签:

【中文标题】是否可以使用智能指针进行切片?【英文标题】:Is it possible for slicing to occur with Smart Pointers? 【发布时间】:2009-10-08 23:12:18 【问题描述】:

如果我正确理解切片,我认为指针或智能指针不会发生这种情况。例如,如果您有:

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”时不会改变。

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

【问题讨论】:

【参考方案1】:

智能指针仍然是指针,因此这样的赋值不会导致切片。切片仅在处理值时发生,而不是指针。但是请注意,模板不知道所指向的项目之间的关系,因此即使 B 派生自 A,shared_pointer&lt;B&gt; 也不会派生自 shared_pointer&lt;A&gt;,因此分配不会(自动)获得自动向上转换,就像使用本机指针一样。

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

切片发生在值上,而不是指针上,所以(鉴于您对 A 和 B 的定义),类似于:

A x = 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&lt;A&gt;holder&lt;B&gt; 是不相关的类型,因此无法进行赋值——如果不添加显式类型转换,它根本无法编译。

【讨论】:

您能否详细说明最后一点:所以分配不会(自动)像使用原生指针那样自动向上转换...谢谢。 【参考方案2】:

你是对的,但它们不一样:你不能评估a-&gt;stuff

【讨论】:

以上是关于是否可以使用智能指针进行切片?的主要内容,如果未能解决你的问题,请参考以下文章

使用智能指针进行继承的 pimpl

模板类的智能指针?

C++智能指针类模板

探索智能指针

判断智能指针是否为 NULL

浅谈ObjectARX智能指针AcDbObjectPointer的用法