2013-09-21 74 views
2

假設我們有以下文件(從C通過B.Stroustup ++編程語言所):C++雙聲明/定義?

stack.h

namespace Stack{ 
    void push(int); 
    int pop(); 
    class Overflow{}; 
} 

stack.cpp

#include "stack.h" 

namespace Stack{ 
    const int max_size = 1000; 
    int v[max_size]; 
    int top; 
    class Overflow{}; 
} 

void Stack::push(int elem){ 
    if(top >= max_size){ 
    throw Overflow(); 
    } 
    v[top++] = elem; 
} 

int Stack::pop(){ 
    if(top <= 0){ 
    throw Overflow(); 
    } 
    return v[--top]; 
} 

我不明白爲什麼stack.h中的類Overflow {}的聲明/定義(?)也必須寫入stack.cpp中?

寫這樣的代碼是完全正確的嗎?

UPDATE

的main.cpp

#include <iostream> 
#include "stack.h" 

using namespace std; 

int main(){ 
    try{ 
    int a = 0; 
    while(true){ 
     Stack::push(a++); 
    } 
    } catch(Stack::Overflow){ 
    cout << "Stack::Overflow exception, YEAH!" << endl; 
    } 

    return 0; 
} 

予編譯代碼與: 克++ main.cpp中stack.cpp -o主

克++的i686-Apple蘋果darwin11-llvm-g ++ - 4.2(GCC)4.2.1(基於Apple Inc. build 5658)(LLVM build 2336.11.00)

UPDATE

嘗試過克++(Ubuntu的/ Linaro的4.7.3-1ubuntu1)(溶液)4.7.3代碼給我一個錯誤:stack.cpp:7:9:錯誤:重新定義'class Stack :: Overflow'。這當然是正確的。

摘要:前面說過的在g ++上的mac版本有一個bug。

+0

對我來說很奇怪。 –

回答

1

因爲沒有它,stack.cpp中將沒有Overflow的定義,並且您無法使用該類,例如throw Overflow();

通常的做法是通過頭文件將接口公開給客戶端,然後在實現文件中包含相同的頭文件。如果我們在這個(相當不尋常)的情況下這樣做,我們還需要公開實現細節(max_size,v[]top)。重複的類定義可以避免這種情況,所以實現細節可以隱藏在客戶端代碼中。擁有多個類定義並不是一個錯誤,只要它們是通過標記形式的無用標記並且不出現在相同的翻譯單元中。

編輯:該問題已被編輯 - 現在有#include "stack.h"在stack.cpp這是以前沒有。

這使得程序不合格 - 在同一個翻譯單元中有兩個類Overflow的定義(記住include指令基本上只是複製 - 粘貼頭文件的內容)。它在本質上,如果你這樣做是相同的:

int i; 
int i; // error: redefinition of i 
int main() {} 

,你可以在整個程序中的類的幾個定義,這一事實實際上是一個例外One Definition Rule

+0

我覺得在接口中定義類而不是聲明它有點讓人誤解。 – Tim

+0

@Tim等一下,你是否編輯了這個問題,並把'include「stack.h」'放在源文件中? – jrok

+0

是的,我把#include「stack.h」放入stack.cpp – Tim