广义拷贝构造函数

Zha*_*dze 15 c++ polymorphism inheritance templates

为什么类shared_ptr在其构造函数中有另一个模板?

例如:

template<class T> class shared_ptr {
public:
  template<class Y>
  explicit shared_ptr(Y * p);
Run Code Online (Sandbox Code Playgroud)

我一直在阅读Scott Meyers的Effective C++,第45项,其中说它背后的想法是通过它们实现多态性; 即,构造shared_ptr<A>shared_ptr<B>如果B从A衍生

但是没有定义像这样的构造函数

explicit shared_ptr(T * p);
Run Code Online (Sandbox Code Playgroud)

足够?我的意思是,这段代码运行得很好:

class C1 {
};

class C2 : public C1 {
};

template<typename T>
class A
{
public:
  A(T &a)
  {
    var1 = a;
  }

  T var1;
};

int main(int argc, char *argv[])
{
  C2 c2;
  A<C1> inst1(c2);
}
Run Code Online (Sandbox Code Playgroud)

那么为什么我们需要另一个构造函数模板呢?

asc*_*ler 13

如果没有模板构造函数,以下代码将具有未定义的行为:

#include <memory>

class Base {};
class Derived : public Base {};

int main() {
    std::shared_ptr<Base> ptr( new Derived );
}
Run Code Online (Sandbox Code Playgroud)

如果shared_ptr只接受a Base*,则强制最终调用deleteBase*指针.但由于Base没有虚拟析构函数并且指针实际指向Derived,这是未定义的行为.

但实际上,上面的代码是格式良好的.模板构造函数用于shared_ptr获取Derived*指针并存储调用delete原始Derived*指针的自定义删除器,这很好.

  • 我认为这是一个很好的解释为什么它对于`std :: shared_ptr`是必要的,但我认为这种模式在标准库中不需要删除器的其他地方很常见. (2认同)
  • 这是自定义删除器的一个相当边际的副作用.它们是一个很好的额外,而不是shared_ptr背后的动力(这是*共享*指针). (2认同)