C ++函数已经定义了吗?

时间:2013-02-22 13:56:32

标签: c++ visual-c++

在cpp文件的顶部,我有

namespace PQL {
    class Synonym {
    ...
    public:
        ...
        int size();
    };
}

// removing the below chunk makes it work
int Synonym::size() {
    return ids.size();
}

为什么底部块会使代码失败?我正在创建函数的实现?其他功能定义类似的方式工作。

更新

Full source on Pastie

我得到的错误如下:

  

Error 1 error LNK2005: "public: int __thiscall PQL::Synonym::size(void)" (?size@Synonym@PQL@@QAEHXZ) already defined in main.obj H:\Dropbox\Sch\CS3202\SPA_CPP\SPA\pql.obj

3 个答案:

答案 0 :(得分:4)

因为Synonym不是全局范围内的名称。

使用

int PQL::Synonym::size() {
    return ids.size();
}

或在命名空间内实现该方法。

答案 1 :(得分:1)

根据您的评论,我把它放在一起:您将所有内容放在一个Cpp文件中,并将该文件包含在不同的其他文件中。每个文件都会编译,每个文件都有PQL::Synonym::size()的实现。链接时,链接器会查看所有这些定义,但不知道选择哪一个。

将代码拆分为标题和源文件,只需在其他文件中包含标题。

答案 2 :(得分:1)

这是因为您的代码位于头文件中并包含在多个编译单元中:

    inline int Synonym::size() {
//  ^^^^^^^
        return ids.size();
    }

添加内联告诉链接器可能有多个定义。

注意:关键字“inline”与现代编译器中的内联代码无关。

作为一个非常重要的说明。

您的头文件包含:

 using namespace std;
 // and
 using namespace PQL;

这是一个非常糟糕的主意。您现在正在强制使用您的代码的任何人。我永远不会使用您的头文件,因为它会污染我的代码并导致无法预料的问题。可以在你自己的源文件中执行此操作(当你知道并理解这些问题时),但是你永远不要强迫其他开发人员使用它。

请参阅:Why is "using namespace std" considered bad practice?