2013-03-31 86 views
0

复制构造函数在下面的代码中失败。我已经刮到了代码清晰模板的复制构造函数

#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 
+0

这里有一件事你为什么在Sptr上有templte T :: Sptr?它已经在类声明中。它会影响它。 – 2013-03-31 19:06:18

+1

不要“为了清晰而剪切代码”,因为现在它甚至没有接近有效的代码,它全是'.'字符,'SPTR'的类定义没有关闭'}',并且您已经定义了一个'SPTR (U *')构造函数没有声明。而是**将代码减少到仍然类似于有效代码的东西。请参阅http://sscce.org/并解决问题。 –

回答

1

您没有必要的构造函数的定义,只有声明:

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

您需要定义它,无论是内嵌在类定义或ouside,如下所示:

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

你在类中声明此构造:

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

但是你还没有显示出一个定义。错误消息说你从来没有定义它。我的猜测是错误信息是正确的。尝试修复。

0

它不应该是

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 
}