2011-09-30 231 views
1

我想在C++中創建一個簡單的模板類。我一直在嘗試編譯以下內容,但我只收到編譯錯誤。這是代碼:模板類析構函數

#include <stdlib.h> 
#include <stdio.h> 

template<int size> 
class array { 
public: 
    int len; 
    int data[size]; 
    array(void) : len(size) {} 
    virtual ~array(void) {} 
}; 

int main() { 
    array<3> a; 
    for (int i=0; i < a.len; ++i) { 
     a.data[i] = i; 
     printf("%d\n", a.data[i]); 
    } 
    return 0; 
} 

這是錯誤的g ++ - 4.2.1是給我:

Undefined symbols: 
    "__Unwind_Resume", referenced from: 
     _main in ccaYob9x.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

如果我們註釋掉析構函數的線,則代碼編譯,因爲它應該和它給我一個數字0,1,2的列表。

在理解模板基類如何工作之後,我的最終目標是創建專門的模板類。我想創建一個多維數組,但我希望專門針對維數爲1,2和3的情況。我主要希望能夠爲這些情況重載operator()。在任何情況下,使用這樣的模板類可以省去在維度爲1,2和3時動態分配內存的麻煩。是否有人知道如何更改代碼以動態分配內存?這樣做將需要您定義析構函數,這是我目前面臨的問題。

編輯:

我不熟悉模板專業化。有人知道如何在size = 1,2和3時製作一個專門的模板以獲得數據的靜態內存,並默認具有動態內存?

編輯2:

看來,我有因爲我的G ++編譯器的麻煩。有誰看到任何與此:

g++ -v 
Using built-in specs. 
Target: i686-apple-darwin10 
Configured with: /var/tmp/gcc/gcc-5666.3~6/src/configure --disable-checking --enable- werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple- darwin10 --with-gxx-include-dir=/include/c++/4.2.1 
Thread model: posix 
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3) 

編輯3:

有一定是有毛病我的g ++版本。我只是用同一臺機器上的g ++ 4.0和macport版本g ++ - mp-4.3來試用它,它工作正常。我想是時候升級到下一個版本了。感謝您的回答和提示。

+1

'func(void)'是一個C語言,在C++中它將是'func()'。 –

+0

在聲明中使用'bar foo(void);'在C++中,正確的方法是'bar foo();'而不是。在C語言中,空括號表示「我不想告訴你參數是什麼」,C++中的含義是「沒有參數」。 – 6502

+0

@ K-ballo,我從構造函數和析構函數中刪除了void,但仍然得到相同的編譯器錯誤。 – jmlopez

回答

3

試試這個:

template<int size> 
class array { 
public: 
    int len; 
    int *data; 
    array(); 
    virtual ~array(void); 
}; 

// 1 dimension specialized array 
template <> 
array<1>::array() : len(1) 
{ 
    data = new int; 
} 

template <> 
array<1>::~array() 
{ 
    delete data; 
} 

template <int size> 
array<size>::array() : len(size) 
{ 
data = new int[size]; 
} 

template <int size> 
array<size>::~array() 
{ 
delete [] data; 
} 

int main(int, char) 
{ 
    array<3> a; 
    for (int i=0; i < a.len; ++i) { 
     a.data[i] = i; 
     printf("%d\n", a.data[i]); 
    } 

    array<1> b; 
    for (int i=0; i < b.len; ++i) { 
     b.data[i] = i; 
     printf("%d\n", b.data[i]); 
    } 

    return 0; 
} 

使用g ++,你不會有編譯錯誤。您可以爲每個不同的數組大小定義專門的operator(),而不會出現問題,如構造函數和析構函數接縫。

+0

謝謝你,我已經回答了我在發佈後幾秒鐘內編輯過的內容。我在我的機器上試過了,但我仍然得到相同的錯誤:'未定義的符號:「__Unwind_Resume」'。我正在使用OS X 10.6。我在g ++ 4.5.1版本的linux機器上嘗試了你的代碼,它工作。我需要做些什麼才能使其在我的Mac中工作?升級g ++? – jmlopez

+0

對不起,我無法幫助你關於OS X.我不知道這是否是一個過時的g ++問題。我不這麼認爲,因爲我正在使用一個非常古老的g ++版本,正好(GCC)4.1.2 20071124(Red Hat 4.1.2-42)。發佈你的編譯和鏈接參數,我們會檢查它們。也許是指另一個代碼部分。 –

+0

請參閱編輯我的Mac上安裝的g ++的信息。 – jmlopez

1

這個問題並不嚴格,但讓我給你一些關於yiour代碼的int提示。

首先:決定是否要使用C或C++。模板是C++,但你是「作爲C程序員編寫的」。並不是說這本身就是不好的,不過這是不言而喻的。 (使用iostream,而不是stdlib.hstdio.h,請不要使用function(void),而只是function())。 可能不是你的情況,但也請檢查你的源代碼沒有「C」擴展名(這可能會愚弄編譯器)並使用g ++(不是gcc)作爲命令(你將鏈接的庫是不同的)

二:注意變量和常量的使用:inst size作爲模板參數,實例化時爲常量。無法保持len變量(在您的設計中,數組大小無法更改):a static const int len = size就是您所需要的。

第三:如果你真的想測試,不要使用單一的for循環分配和讀取數值:這會使你在指標的情況下,完全失明濫用:不是a.data[i]試錯a.data[0],你會得到完全一樣的輸出。使用循環來填充數組,然後用另一個循環來讀取它。第四:在C++中,作用域很重要:保持打開和關閉大括號{}對齊。這可能聽起來很迂腐,但救了我很多次......

+0

我使用g ++作爲我的命令。 stdlib.h是我的一個壞習慣。我會盡力擺脫它。我真的很喜歡你的第二點。這是我在某個時候需要的東西,但我從來沒有想過我可以按照你提到的方式來完成。 3:我通常這樣做,但我試圖保持這個例子的簡短。 – jmlopez