简体   繁体   English

模板类“复制构造函数”

[英]Templated Class “Copy Constructor”

I've come across this templated smart pointer class Cptr shown partially below, and I don't understand one of the method implementations and was hoping to get some input. 我遇到了下面部分显示的这种模板化的智能指针类Cptr,但我不了解其中一种方法的实现,希望获得一些输入。 My question is on 'Method 2', labeled below. 我的问题是关于“方法2”的,标签如下。 Specifically, if Cptr is templated by T, what call syntax is available that allows 'Method 2' to be called, which appears, at least to me, to be a copy constructor, but I thought copy constructors are not templated. 具体来说,如果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;
}

I envisioned a call to method 2 like so: 我设想了对方法2的调用,如下所示:

Cptr<float> B( new float(1.1) );
Cptr<int> A(B); //error for different types

But the assignment of pointers of different types does not make much sense to me. 但是对我来说,分配不同类型的指针没有多大意义。 Has anyone come across a method definition like 'Method 2' and if so what are the uses? 有谁遇到过像“方法2”这样的方法定义,如果有的话,有什么用? Thanks very much for your time. 非常感谢你花时间陪伴。

First of all, copy constructors can certainly be a template, loosely speaking. 首先,松散地说,复制构造函数当然可以是模板。 Technically, a copy constructor is a constructor from another instance of the same class, but you can certainly define a constructor that takes a reference to another class as a parameter. 从技术上讲,复制构造函数是同一个类的另一个实例的构造函数,但是您当然可以定义一个将对另一个类的引用作为参数的构造函数。

However, the answer to your primary method is that "Method2" allows the smart pointer to be assigned from a smart pointer to a different class, as long as the implied type conversion is allowed: 但是,您的主要方法的答案是,只要允许隐式类型转换,“ Method2”就可以将智能指针从智能指针分配给其他类:

class Base {};

class Derived : public Base {};

Cptr<Derived> d;

Cptr<Base> b=d; // "Method2" will be used here.

This smart pointer implementation allows a smart pointer to a derived class to be assigned to a smart pointer to the base class. 该智能指针实现允许将指向派生类的智能指针分配给指向基类的智能指针。

Normally, Cptr<Base> and Cptr<Derived> are two completely unrelated classes. 通常, Cptr<Base>Cptr<Derived>是两个完全不相关的类。 Each template instance is a separate class. 每个模板实例都是一个单独的类。 And you can't normally assign an instance of one class to an instance of a completely unrelated class, unless an appropriate conversion is available. 而且,除非可以进行适当的转换,否则通常不能将一个类的实例分配给完全不相关的类的实例。

Just like you can assign an ordinary pointer to a derived class to a pointer to a base class, this smart pointer provides comparable functionality. 就像可以将派生类的普通指针分配给基类的指针一样,此智能指针提供了可比的功能。

First of all, you are right. 首先,你是对的。 Copy constructors cannot be templates. 复制构造函数不能是模板。 §12.8/2 says (emphasis by myself): §12.8/ 2说(我自己强调):

A non-template constructor for class X is a copy constructor if its first parameter is of type X& , const X& , volatile X& or const volatile X& , and either there are no other parameters or else all other parameters have default arguments [...] 如果类X 非模板构造函数的第一个参数为X&const X&volatile X&const volatile X& ,并且没有其他参数,或者所有其他参数都有默认参数,则为复制构造const X& 。 ]

But method 2 is not a copy constructor, because Cptr<S> is a different class than Cptr<T> . 但是方法2不是复制构造函数,因为Cptr<S>是与Cptr<T>不同的类 It is just a normal constructor, not really much different to, say, Cptr(int i) or Cptr(std::string const& s) . 它只是一个普通的构造函数,与Cptr(int i)Cptr(std::string const& s)没有太大不同。 And normal constructors can be templates. 普通的构造函数可以是模板。

Of course, you can assume that Cptr<U> will have the same members as Cptr<T> . 当然,您可以假定Cptr<U>Cptr<T>具有相同的成员。 That's what the implementation of the constructor does. 这就是构造函数的实现。 It would not work, for example, if Cptr was specialised for that U and those members did not exist. 例如,如果Cptr专门用于该U而这些成员不存在,那将是行不通的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM