【问题标题】:C++ double declaration / definition?C++双重声明/定义?
【发布时间】:2013-09-21 18:14:08
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ exception declaration


    【解决方案1】:

    因为没有它,stack.cpp中就没有Overflow的定义,你也不能使用这个类,比如throw Overflow();

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

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

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

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

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

    【讨论】:

    • 我发现在接口中定义类而不是声明它有点误导。
    • @Tim 等一下,您是否编辑了问题并将include "stack.h" 放入源文件中?
    • 是的,我把#include "stack.h" 放入stack.cpp
    • 那里没有初始化,不是吗?因为现在代码格式不正确,同一个翻译单元中不能有两个定义。
    • 您编译的代码必须与问题中的代码不同。
    猜你喜欢
    • 2021-09-22
    • 2015-06-30
    • 1970-01-01
    • 2010-10-04
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    相关资源
    最近更新 更多