基类构造函数的多重定义?

时间:2015-05-22 01:44:27

标签: c++

我正在创建一些类来封装套接字IO。我已经创建了一个基类来抽象出常见数据(文件描述符,端口#s等)和功能(大部分初始化)。我的代码看起来像这样 -
base.hpp

class Base { 
    protected:
        Base(int port);
        ~Base();
        // common data
};
Also here I have the implementations of the constructor and destructor

client.hpp

#include base.hpp
class Client : private Base {
    // constructor and other required code
}

testclient.cpp

#include "client.cpp"
int main() {
    Client c (ip, port);
    ... more stuff
    return 0;
}

我还在client.cpp中实现了客户端类,并且它的构造函数适当地调用了基本构造函数。我也有正确而独特的头部防护。但是,当将client.o与testclient链接时,我会引用链接器错误,引用Base构造函数和析构函数的多个定义。我究竟做错了什么?我会包含代码,但它很长,我确信我的错误是由于一些#include / linked magic。

3 个答案:

答案 0 :(得分:1)

如果函数在头文件中实现,则必须使用inline声明函数的定义,以防止对函数进行多种定义。

修复将inline放在实现前面的错误。例如,Base的构造函数

inline Base::Base(int port)
^^^^^^ Difference here
{
    // Implementation
}

您也可以在类中实现方法。

inline通知编译器该函数可以在多个.cpp文件中编译(在类定义中声明的函数是隐式声明的inline。)如果函数未声明为{{1}它从每个.cpp文件导出。当链接器出现时,在编译程序之后,每个.cpp文件中都有一个包含标题的函数定义。这会导致链接器出错。

答案 1 :(得分:0)

选项1:

在标头文件client.hpp中:

class Base { 
    protected:
        Base(int port) {
           ...
        }

        ~Base() {
           ...
        }
};

选项2:

在标头文件client.hpp中:

class Base { 
    protected:
        Base(int port);
        ~Base();
};

在源文件client.cpp中:

Base::Base(int port) {
   ...
}

Base::~Base() {
   ...
}

答案 2 :(得分:0)

#include base.hpp应为此#include "base.hpp"#include "base.h"