模板的复制构造函数

Copy constructor for templates

本文关键字:构造函数 复制      更新时间:2023-10-16

复制构造函数在以下代码中失败。为了清晰,我已经剪辑了代码

#include <iostream>
#include <stdio.h>
#include <assert.h>
namespace my {
    template <class T>
    class Sptr {
    private:
        //some kind of pointer
            //one to current obj
        T* obj;
.
.
.
    public:
.
.
.
        Sptr(const Sptr &);
        template <typename U> 
        Sptr(const Sptr<U> &);
.
.
.
};//Class ends
    template <typename T>
    template <typename U> 
    Sptr<T>::Sptr(U* u) {
        //do something
    }
    template <typename T>
    Sptr<T>::Sptr(const Sptr<T> &copyObj) {
        //do copy constructor stuff
    }
.
.
.
}
using namespace std;
using namespace my;
/* Basic Tests 1 ================================================================================ */
size_t AllocatedSpace;
class Base1 {
    protected:
        Base1() : derived_destructor_called(false) {
            printf("Base1::Base1()n");
        }
    private:
        Base1(const Base1 &); // Disallow.
        Base1 &operator=(const Base1 &); // Disallow.
    public:
        virtual ~Base1() {
            printf("Base1::~Base1()n");
            assert(derived_destructor_called);
        }
    protected:
        bool derived_destructor_called;
};
class Derived : public Base1 {
        friend void basic_tests_1();
    private:
        Derived() {}
        Derived(const Derived &); // Disallow.
        Derived &operator=(const Derived &); // Disallow.
    public:
        ~Derived() {
            printf("Derived::~Derived()n");
            derived_destructor_called = true;
        }
        int value;
};

这个测试代码行产生错误Sptr<Base1> sp3(sp);

void basic_tests_1() {

    //size_t base = AllocatedSpace;
    // Test deleting through original class.
    {
        // Base1 assigned from Sptr<Derived>.
        {
            Sptr<Base1> sp2;
            {
                Sptr<Derived> sp(new Derived);
                // Test template copy constructor.
                Sptr<Base1> sp3(sp);
                sp2 = sp;
                sp2 = sp2;
            }
        }
    }
}
错误:

/tmp/ccKrn1xG.o: In function `basic_tests_1()':
Sptr.cpp:(.text+0x81): undefined reference to `my::Sptr<Base1>::Sptr<Derived>(my::Sptr<Derived> const&)'
collect2: error: ld returned 1 exit status

您已经在类中声明了这个构造函数:

    template <typename U> 
    Sptr(const Sptr<U> &);

但是你没有给出定义。错误消息说您从未定义过它。我猜错误信息是正确的。

您没有所需构造函数的定义,只有声明:

    template <typename U> 
    Sptr(const Sptr<U> &);

你需要定义它,要么内联在类定义内,要么在类定义外,如下所示:

template <typename T>
template <typename U> 
Sptr<T>::Sptr(const Sptr<U> &u) {
    // do something
}

应该是

template <typename T>
template <typename U> 
Sptr<T>::Sptr(const U& u) {
    //do something
}
不是

template <typename T>
template <typename U> 
Sptr<T>::Sptr(U* u) {
    //do something
}