我遇到过这个模板化的智能指针类Cptr,部分显示在下面,我不理解其中一个方法实现,并希望获得一些输入。我的问题是关于'方法2',标记如下。具体来说,如果Cptr由T模板化,那么可以使用哪种调用语法来允许'方法2'被调用,至少在我看来,它是一个复制构造函数,但我认为复制构造函数不是模板化的。
template <class T> class Cptr
{
public:
/* Constructors ... */
/* Getters ... */
T* ptr() const { return p_; }
long* cnt() const { return cnt_; }
/* Copy Constructors? */
//Method 1
Cptr<T>(const Cptr<T>& i)
: ptr_(i.ptr()), cnt_(i.ptr())
{
std::cout << "M1" << std::endl;
++(*cnt);
}
//Method 2
template <class S> Cptr(const Cptr<S>& i)
: ptr_(i.get()), cnt_(i.cnt())
{
std::cout << "M2" << std::endl;
++(*cnt_);
}
private:
T* p_;
int* cnt_;
};
int main(int argc, char* argv[])
{
CPtr<int> A(new int(5));
CPtr<int> B(A);
std::cout << *(B.get()) << std::endl;
return EXIT_SUCCESS;
}
我设想调用方法2,如下所示:
Cptr<float> B( new float(1.1) );
Cptr<int> A(B); //error for different types
但是对不同类型的指针的赋值对我来说没有多大意义。有没有人遇到类似于&#39;方法2&#39;的方法定义?如果有的话有什么用途?非常感谢您的时间。
答案 0 :(得分:3)
首先,松散地说,复制构造函数当然可以是一个模板。从技术上讲,复制构造函数是来自同一个类的另一个实例的构造函数,但您当然可以定义一个构造函数,该构造函数将另一个类的引用作为参数。
然而,您的主要方法的答案是&#34;方法2&#34;允许智能指针从智能指针分配到不同的类,只要允许隐含的类型转换:
class Base {};
class Derived : public Base {};
Cptr<Derived> d;
Cptr<Base> b=d; // "Method2" will be used here.
这个智能指针实现允许将派生类的智能指针分配给指向基类的智能指针。
通常,Cptr<Base>
和Cptr<Derived>
是两个完全不相关的类。每个模板实例都是一个单独的类。除非有适当的转换,否则您通常无法将一个类的实例分配给完全不相关的类的实例。
就像你可以将指向派生类的普通指针分配给指向基类的指针一样,这个智能指针提供了类似的功能。
答案 1 :(得分:2)
首先,你是对的。复制构造函数不能是模板。 §12.8/ 2说(我自己强调):
类
X
的非模板构造函数是一个复制构造函数,如果它的 第一个参数的类型为X&
,const X&
,volatile X&
或const volatile X&
,并且没有其他参数或其他所有参数 参数有默认参数[...]
但方法2不是复制构造函数,因为 Cptr<S>
与Cptr<T>
不同。它只是一个普通的构造函数,与Cptr(int i)
或Cptr(std::string const& s)
没有太大区别。而普通的构造函数可以是模板。
当然,您可以假设Cptr<U>
与Cptr<T>
具有相同的成员。这就是构造函数的实现。例如,如果Cptr
专门用于U
并且那些成员不存在,那么它将不起作用。