2013-09-21 63 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