为什么像shared_ptr
这样的类在其构造函数中有另一个模板?
例如:
template<class T> class shared_ptr {
public:
template<class Y>
explicit shared_ptr(Y * p);
我一直在阅读Scott Meyers的 Effective C ++ ,第45项,其中说它背后的想法是通过它们实现多态性;也就是说,如果B来自A,则从shared_ptr<A>
构造shared_ptr<B>
。
但是没有定义像
这样的构造函数explicit shared_ptr(T * p);
足够?我的意思是,这段代码运行得很好:
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);
}
那么为什么我们需要另一个构造函数模板呢?
答案 0 :(得分:13)
如果没有模板构造函数,以下代码将具有未定义的行为:
#include <memory>
class Base {};
class Derived : public Base {};
int main() {
std::shared_ptr<Base> ptr( new Derived );
}
如果shared_ptr
只占用Base*
,则会强制最终在delete
指针上调用Base*
。但由于Base
没有虚拟析构函数且指针实际指向Derived
,因此这是未定义的行为。
但实际上,上面的代码是格式良好的。 shared_ptr
的模板构造函数使用Derived*
指针并存储在原始delete
指针上调用Derived*
的自定义删除器,这很好。
答案 1 :(得分:0)
explicit shared_ptr(T * p);
如果shared_ptr
只有这个构造函数,它就会破坏它的整个目的,即提供一个引用计数指针。
引用计数(或者更确切地说是指针)是shared_ptr
的一部分。每次创建,销毁或复制shared_ptr
时都应更新它。如果将shared_ptr
传递给复制例程,则只能实现最后一部分。传递裸指针将创建引用计数为1的shared_ptr
。
引用计数指针仅在其引用计数超过1时共享。对于您的方案,不清楚这是如何发生的。
一些引用计数功能由普通(非模板)复制构造函数提供。但不是全部。
例如,
std::shared_ptr<Derived> d;
std_shared_ptr<Base> b;
...
b = d;
如果没有模板“copy”构造函数,将无法编译。我们希望共享poiters提供与普通指针相同的多态行为,因此我们希望上述构造为Just Work。模板构造函数提供了。