2

假设我们有以下文件(取自 B.Stroustup 的 The C++ Programming language):

堆栈.h

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

堆栈.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中?

编写这样的代码完全正确吗?

更新

主文件

#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: error: redefinition of 'class Stack::Overflow'。这当然是正确的。

总结:之前说的mac上的g++版本有bug。

4

1 回答 1

1

因为没有它,就没有Overflowin stack.cpp 的定义,并且您无法使用该类,例如 in throw Overflow();

通常的做法是通过头文件向客户端公开接口,然后在实现文件中包含相同的头。如果我们要在这种(相当不寻常的)情况下这样做,我们还需要公开实现细节(max_sizev[]top)。重复的类定义是为了避免这种情况,因此可以从客户端代码中隐藏实现细节。拥有多个类定义并不是错误,前提是它们是逐个标记相同的并且不存在于同一个翻译单元中。

编辑:问题已被编辑 - 现在#include "stack.h"stack.cpp 中有以前不存在的。

这使得程序格式错误 - 在同一个翻译单元中有两个类定义Overflow(请记住,include 指令基本上只是复制粘贴头文件的内容)。本质上与您执行此操作相同:

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

您可以在整个程序中对一个类进行多个定义这一事实实际上是一个定义规则的一个例外。

于 2013-09-21T08:39:50.283 回答