假设我们有以下文件(取自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编写?
编写此类代码是否正确?
更新
的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;
}
我用以下代码编译代码: g ++ main.cpp stack.cpp -o main
g ++ i686-apple-darwin11-llvm-g ++ - 4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2336.11.00)
更新(解决方案)
尝试 g ++(Ubuntu / Linaro 4.7.3-1ubuntu1)4.7.3 代码给了我一个错误:stack.cpp:7:9:错误:重新定义'class Stack ::溢出'。这当然是正确的。
总结:之前提到的mac上的g ++版本有一个错误。
答案 0 :(得分:1)
因为没有它,stack.cpp中就没有Overflow
的定义,你也无法使用该类,例如在throw Overflow();
中。
通常的做法是通过头文件将接口暴露给客户端,然后在实现文件中包含相同的头。如果我们在这个(相当不寻常的)情况下这样做,我们还需要公开实现细节(max_size
,v[]
和top
)。重复的类定义是为了避免这种情况,因此可以从客户端代码中隐藏实现细节。如果它们是令牌的缩进令牌并且不存在于同一个翻译单元中,则具有多个类定义并不是错误。
编辑:问题已被修改 - 现在stack.cpp中有#include "stack.h"
以前没有。
这使得程序格式错误 - 在同一翻译单元中有两个类Overflow
的定义(请记住,include指令基本上只是复制粘贴头文件的内容)。它本质上就像你这样做:
int i;
int i; // error: redefinition of i
int main() {}
事实上,您可以在整个程序中拥有多个类的定义,这实际上是One Definition Rule的一个例外。