2010-04-21 78 views
2

我实现了引用计数指针(在本例中被称为SP),我遇到了多态性问题,我认为我不应该这样做。智能指针和多态性

在下面的代码:从BaseClass

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

DerivedClass继承。使用普通的指针这应该已经工作了,但用智能指针它说"cannot convert from 'SP<T>' to 'const SP<T>&",我认为它指的是智能指针的复制构造函数。

如何让这种多态与引用计数指针? 我很欣赏代码示例,因为如果我遇到这个问题,显然我会在这里做一些错误。

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

+0

请发布复制构造函数的代码。 – Danvil 2010-04-21 11:53:14

+0

在阅读模板错误消息时,注意每个位置中“T”的含义非常重要。该错误可能表示类似无法将[SP = ]与[T = DerivedClass]转换为常量SP ,并且[T = BaseClass]'表示额外信息是解决方案的一半。 – 2010-04-21 18:38:00

回答

6

相当明显:

SP<DerivedClass> retPtr = new DerivedClass(); 

应该是:

SP<BaseClass> retPtr = new DerivedClass(); 
+2

将SP 转换为SP 对于良好的智能指针实现应该没有问题。 – Danvil 2010-04-21 11:54:23

+0

这解决了'foo()'中的特定问题,但它并不适用于可能需要转换的其他地方的自然语法。 – Gorpik 2010-04-21 12:02:48

+1

@Danvil:转换不是问题,除非在有限的情况下(协变引用和指针),否则不能更改重载函数的返回类型,因此甚至无法创建错误类型的“SP”也没有意义。这个答案最简单:创建一个实际返回类型的对象。 – 2010-04-21 12:04:13

0

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

template <class Base> 
class SP 
{ 
    ... 

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

(也许拷贝构造函数,太)?

4

您应该添加的隐式转换构造函数SP<T>

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

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

模板构造函数绝不是复制构造函数。复制构造函数不会帮助;这是一个非显式的转换构造函数。 – 2010-04-21 12:17:35

+0

@Charles。对。不管。 – 2010-04-21 12:24:03

0

除了拷贝构造函数:

SP(const SP<T>& ref); 

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

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

否则,编译器将不知道如何构造SP<BaseClass>SP<DerivedClass>;对他而言,他们是无关的。

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