2013-03-31 85 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 
}