2009-10-28 46 views
0

這裏是我有什麼(不工作)的簡化版本:如何在C++中使用常量數組的成員函數?

prog.h:

... 
const string c_strExample1 = "ex1"; 
const string c_strExample2 = "ex2"; 
const string c_astrExamples[] = {c_strExample1, c_strExample2}; 
... 

prog.cpp:

... 
int main() 
{ 
    int nLength = c_astrExamples.length(); 
    for (int i = 0; i < nLength; i++) 
     cout << c_astrExamples[i] << "\n"; 
    return 0; 
} 
... 

當我嘗試建立,我得到以下錯誤: 錯誤C2228:'.length'的左邊必須有class/struct/union

只有當我嘗試使用成員func c_astrExamples的部分。 如果我用數字2替換「c_astrExamples.length()」,一切似乎都正常工作。

我能夠使用c_strExample1和c_strExample2的成員函數,所以我認爲行爲出現在我使用字符串與字符串數組之間的一些區別。

我在prog.h中的初始化是否錯誤?我需要prog.cpp中特別的東西嗎?

回答

6

C++中的數組沒有成員函數。如果你想要一個對象,你應該使用像vector<string>集合,或計算這樣的長度:

int nLength = sizeof(c_astrExamples)/sizeof(c_astrExamples[0]); 
+0

@Grumdrig:你需要開始一個新的句子:」 .. .vector 。如果你......' – quamrana 2009-10-28 19:12:39

+4

@quamrana - Grumdrig的句子正確解析我。 「如果你想要,你應該使用X,否則就這樣做。」完美的語法結構。 – asveikau 2009-10-28 19:15:41

+1

我還會注意到提問者比他小心sizeof()。它經常混淆新手,它不會告訴你編譯器不知道的任何東西的大小,例如。動態分配的內存,或作爲參數傳遞給函數的東西。 – asveikau 2009-10-28 19:21:03

0

c_astrExamples是一個數組,其中沒有「length()」方法。

2

數組在C++是由C,這是不是面向對象的繼承。所以它們不是對象,也沒有成員函數。 (因爲它們的行爲類似於int,float和其他內置類型)。從該血統中解決了數組的更多問題,例如它們很容易(例如,當傳入函數時)衰減爲指向第一個元素的指針沒有大小信息。

通常的建議是使用std::vector來代替,這是一個動態調整大小的數組。但是,如果數組大小在編譯時已知,並且您需要一個常量,那麼boost's array typeboost::array,如果您的編譯器支持TR1標準擴展也可以使用std::tr1::array,在下一版本的C++標準中變爲std::array)是你想要什麼。

編輯1

一種安全的方式來獲得C中的數組的長度++涉及扔進組合的模板,函數指針,甚至宏不可思議的組合:

template <typename T, std::size_t N> 
char (&array_size_helper(T (&)[N]))[N]; 

#define ARRAY_SIZE(Array_) (sizeof(array_size_helper(Array_))) 

如果你(像我一樣)認爲這很搞笑,看看boost::array

編輯2

由於dribeas在評論說,如果你不需要編譯時間常數,這

template <typename T, std::size_t N> 
inline std::size_t array_size(T(&)[N]) 
{return N;} 

是足夠了(更容易閱讀和理解)。

+0

感謝關於衰減到指向第一個元素的指針的附加註釋。 這解釋了我得到的那一刻的行爲,讓我相信我有一個指向數組的指針。 – 2009-10-28 19:16:29

+2

這裏的一個重要注意事項是模板調用中的template + sizeof()將提供編譯時間常量。還有其他更簡單,更易讀的語法,它們是安全的,但會產生一個運行時值:'template inline std :: size_t array_size(T(&)[N]){return N; }'是安全的,大多數編譯器都會在編譯時被內聯和翻譯成常量(沒有運行時開銷),但它不是一個可以在元編程中使用的「編譯時常量」。 – 2009-10-28 21:40:54

0

在C++數組中不是對象,也沒有任何方法。如果您需要獲取陣列的長度,您可以使用以下宏:

#define COUNTOF(array) (sizeof(array)/sizeof(array[0])) 
int nLength = COUNTOF(c_astrExamples); 
+0

請注意,這個宏的缺點是它使用'array'作爲指針進行編譯。 (嘗試'sizeof(0 [array])',而不是指針,但是與數組一起工作。) – sbi 2009-10-28 19:20:30

+0

@sbi:'0 [指針]'應該怎麼失敗?就我所知,這在C++中是一個有效的操作。 (至於g ++ 4.0認爲) – 2009-10-28 21:38:00

+0

@dribeas:我認爲你是對的。所以從頭開始。 ':('' – sbi 2009-10-28 22:17:38

-1

此外,請注意頭文件中的初始化。您有冒犯冒犯鏈接器的風險。
你應該有:

prog.h:

extern const string c_strExample1; 
extern const string c_strExample2; 
extern const string c_astrExamples[]; 
+0

對於'const'對象,我認爲這不是真的。 – sbi 2009-10-28 19:16:06

+0

@sbi:你說得很對,但它並沒有傷害,以防'const'被刪除。 – quamrana 2009-10-28 19:28:10

+0

@quamrana :有時它會受到傷害,所以要小心:在'struct X {static const int k = 5;};'中,''X :: k''可以用作編譯時常量(例如,用於指定堆棧數組如果它已經在類的cpp文件中被初始化了,那麼這是不可能的,而且,一個全局常量變成一個_global變量_應該引起一些問題,那麼Paul的代碼在鏈接 - 時間可能被認爲是一個優勢。 – sbi 2009-10-29 09:34:22

2

只需使用字符串代替STL vector數組:

#include <string> 
#include <vector> 
using namespace std; 

const string c_strExample1 = "ex1"; 
const string c_strExample2 = "ex2"; 
vector<string> c_astrExamples; 
c_astrExamples.push_back(c_strExample1); 
c_astrExamples.push_back(c_strExample2); 

int main() 
{ 
    int nLength = c_astrExamples.size(); 
相關問題