【问题标题】:How is std::shared_ptr polymorphic?std :: shared_ptr多态?
【发布时间】:2015-06-01 05:37:14
【问题描述】:

我正在开发一些容器类,它有类似的想法:在里面保存指针。

#include <iostream>

template<class T>
class Container
{
public:
    Container ( )
    {
         pointer = new T ( );
    }

    ~Container ( )
    {
        delete pointer;
    }

    T* operator->( )
    {
        return pointer;
    }
private:
     T* pointer;
};

struct Base
{
    virtual void who ( )
    {
        std::cout << "Base" << std::endl;
    }
};


struct Child : public Base
{
    virtual void who ( ) override
    {
        std::cout << "Child" << std::endl;
    }
};

void testContainer ( Container<Base> c )
{
    c->who ( );
}

void testSharedPtr ( std::shared_ptr<Base> s )
{
    s->who ( );
}

int main ( )
{
    Container<Child> child;
    std::shared_ptr<Child> sharedChild;

    testSharedPtr ( sharedChild );
    testContainer ( child );
}

此代码编译失败:error C2664: 'void test(Container&lt;Base&gt; &amp;)' : cannot convert argument 1 from 'Container&lt;Child&gt;' to 'Container&lt;Base&gt; &amp;'
但是使用std::shared_ptr&lt;Base&gt;,而不是Container,一切正常。所以问题是:
std::shared_ptr-like 多态可以实现吗?还是这个功能,它以某种方式在 C++ 中硬编码?对不起我的原始语言。

【问题讨论】:

  • 你看过std::shared_ptr的界面,尤其是constructor overloads吗?那可能会回答你的问题。另请注意,即使使用std::shared_ptr,您的代码也不会编译,因为该函数采用非常量引用。 VS 有一个允许它的扩展,但通常临时(例如来自隐式转换的那些)不能绑定到非 const 左值引用。
  • 我的错,已编辑!谢谢
  • 不过,看看下面的答案,您的解决方案似乎不适用于我的情况。

标签: c++ c++11 std shared-ptr


【解决方案1】:

实现以下构造函数:

template<class Other,
         class = typename std::enable_if<std::is_convertible<Other*, T*>::value>::type>
Container(const Container<Other>& _Other) 
{
    pointer = _Other.pointer;
}

仅当Other* 可转换为T* 时才会启用此构造函数,如果TOther 的基类,情况显然会如此。

【讨论】:

  • 不幸的是,这将导致指针上的delete 被调用两次。
  • Jup,没错。他必须实施另一种行为。
  • 谢谢,应该还有friend class Container;
  • 为什么?构造函数可以访问同一模板类的其他实例的私有成员,而无需使用friend-声明。
  • 我的 MSVS2013 编译器不同意你的说法。 error C2248: 'Container&lt;Child&gt;::pointer' : cannot access private member declared in class 'Container&lt;Child&gt;'
猜你喜欢
  • 2012-04-28
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 2014-03-25
  • 2019-10-20
  • 1970-01-01
  • 2011-09-27
  • 2013-06-12
相关资源
最近更新 更多