【问题标题】:cast from templated derived class to template base class从模板派生类转换为模板基类
【发布时间】:2017-01-13 20:17:01
【问题描述】:

我正在实现一个 shared_pointer 模板,它包含一个指向类型名 T 的指针 我想实现一个接收共享指针类(包含指向派生类(O)的指针)的复制构造函数(带有基类(T)的指针)。 如何将接收到的指针从 Base 类型转换为 shared_ptr?

template <typename T>
class Shared_Ptr
{
public:
    template <typename O>friend class Shared_Ptr;    
    template <typename O>
    Shared_Ptr(const Shared_Ptr<O>& other_);
private:
    struct PtrVal
    {
        PtrVal(T* ptr);
        ~PtrVal();
        T *m_ptr;
        size_t m_count;
    };

    PtrVal *m_val;  
};

如何实现 Copy-Constructor??

template <typename T>
template <typename O>
Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_): 
m_val(static_cast<const Shared_Ptr<T> >(other_).m_val)
{}

这会编译,但在运行时会出现分段错误(核心转储)。

我找到了另一种解决方案,但它真的很难看: 我将 other_ 的 m_ptr 转换为 T*(而不是 O*),然后将 O 的 m_val 转换为 T 的 m_val

Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_)
{
    if(dynamic_cast<T *>(other_.m_val->m_ptr))
    {}

    m_val = (Shared_Ptr<T>::PtrVal *)other_.m_val;
}

有什么更好的建议吗? 谢谢

【问题讨论】:

  • 查看 boost::shared_ptr 和 std::shared_ptr 的源代码。您会看到删除器也存储在控制块中(这对于类型擦除很重要)。
  • 你应该用术语更准确,你所说的copy ctor不是一个。

标签: c++ templates casting derived


【解决方案1】:

您要转换m_ptr,而不是other_,因为Shared_Ptr&lt;O&gt;Shared_Ptr&lt;T&gt; 没有继承关系。

template <typename T>
template <typename O>
Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_):
    m_val (static_cast<T*>(other_.m_val->m_ptr))
{}

您还必须更新计数器。

【讨论】:

  • 不是一个好主意,这将允许指向基址的指针转换为派生,这不应该发生。
  • @Slava 我同意这是一个坏主意,因为没有类型检查。我只是回答被问到的问题。也许 shkopa 知道他在调用这个“强制转换构造函数”时做了什么。
  • 那你答错了,因为没有static_cast它可以正常工作。
  • 你的意思是m_val (other_.m_val-&gt;m_ptr)?如果是,这将永远不会让你失望。
猜你喜欢
  • 2019-11-09
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 2016-08-17
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
相关资源
最近更新 更多