【问题标题】:Smart pointers and polymorphism智能指针和多态
【发布时间】:2010-04-21 11:48:41
【问题描述】:

我实现了引用计数指针(在示例中称为 SP),但我遇到了我认为不应该出现的多态性问题。

在以下代码中:

    SP<BaseClass> foo()
    {   
        // Some logic...
        SP<DerivedClass> retPtr = new DerivedClass();
        return retPtr;
    }

DerivedClass 继承自 BaseClass。使用普通指针这应该可以工作,但使用智能指针它说"cannot convert from 'SP&lt;T&gt;' to 'const SP&lt;T&gt;&amp;",我认为它指的是智能指针的复制构造函数。

如何使用引用计数指针允许这种多态性? 如果我遇到这个问题,我会很感激代码示例,因为显然我在这里做错了。

PS:请不要告诉我使用带有智能指针的标准库,因为目前这是不可能的。

【问题讨论】:

  • 请贴出复制构造函数的代码。
  • 在阅读模板错误信息时,请务必注意每个位置的T 的含义。该错误可能表示无法从SP&lt;T&gt; with [T = DerivedClass] to const SP&lt;T&gt; &amp; with [T=BaseClass] 转换,额外的信息是解决方案的一半。

标签: c++ templates polymorphism smart-pointers


【解决方案1】:

相当明显:

SP<DerivedClass> retPtr = new DerivedClass();

应该是:

SP<BaseClass> retPtr = new DerivedClass();

【讨论】:

  • 将 SP 转换为 SP 对于一个好的智能指针实现应该没有问题。
  • 这修复了foo() 中的特定问题,但它不会在其他可能需要转换的地方形成自然语法。
  • @Danvil:转换不是问题,除非在有限的情况下(协变引用和指针),否则您无法更改重载函数中的返回类型,因此即使创建 SP 也毫无意义类型错误。这个答案是最简单的:创建一个实际返回类型的对象。
【解决方案2】:

你应该为SP&lt;T&gt;添加隐式转换构造函数:

template<class T>
struct SP {
   /// ......
   template<class Y>
   SP( SP <Y> const & r )
    : px( r.px ) // ...
    {
    }

   //....
private:
   T * px;
}

【讨论】:

  • 模板构造函数永远不是复制构造函数。复制构造函数无济于事。这是一个非显式转换构造函数。
【解决方案3】:

为什么不添加模板赋值运算符:

template <class Base>
class SP
{
    ...

    template<class Derived>
    operator = (SP<Derived>& rhs)
    {
        ...

(也许还有复制构造函数)?

【讨论】:

    【解决方案4】:

    除了复制构造函数:

    SP(const SP<T>& ref);
    

    你需要一个转换构造函数:

    template<typename T2>
    SP(const SP<T2>& ref);
    

    否则,编译器将不知道如何从SP&lt;DerivedClass&gt; 构造SP&lt;BaseClass&gt;;对他来说,它们是无关的。

    转换构造函数相当简单,因为您可以在内部自动将*DerivedClass 转换为*BaseClass。代码可能与复制构造函数的代码非常相似。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-10
      • 2013-05-07
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多