首页 > 解决方案 > 将单个 C++ 程序分解为具有继承的多文件程序

问题描述

考虑根据注释将以下代码分解为文件

// parent.h
#pragma once
class parent{
public:
    virtual ~parent() =0;
};
parent::~parent(){}


// child.h
#pragma once
#include "parent.h"
class child: public parent{
public:
    ~child();
};


// child.cpp
#include "child.h"
child::~child(){}


// main.cpp
#include "parent.h"
#include "child.h"
int main(){}

编译上面的代码g++ main.cpp child.cpp会出现以下错误:

duplicate symbol __ZN6parentD2Ev in:
    /var/folders/cr/zst9m2t112929f2wg4pkckjc0000gn/T/main-856b8b.o
    /var/folders/cr/zst9m2t112929f2wg4pkckjc0000gn/T/child-18a967.o
duplicate symbol __ZN6parentD1Ev in:
    /var/folders/cr/zst9m2t112929f2wg4pkckjc0000gn/T/main-856b8b.o
    /var/folders/cr/zst9m2t112929f2wg4pkckjc0000gn/T/child-18a967.o
duplicate symbol __ZN6parentD0Ev in:
    /var/folders/cr/zst9m2t112929f2wg4pkckjc0000gn/T/main-856b8b.o
    /var/folders/cr/zst9m2t112929f2wg4pkckjc0000gn/T/child-18a967.o
ld: 3 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

但是在单个文件中运行这个非常相似的程序可以编译并运行良好

class parent{
public:
    virtual ~parent() =0;
};
parent::~parent(){}

class child: public parent{
public:
    ~child();
};

child::~child(){}

int main(){}

为什么是这样?如何在不导致编译错误的情况下将第二个单文件程序分解为多文件程序,错误是什么以及导致它的原因是什么?

谢谢

标签: c++

解决方案


正如链接器所说,您parent的析构函数有多个定义。换句话说,这个定义:

parent::~parent(){}

出现在main.cppchild.cpp中。

要解决此问题,您可以:

  • 将定义移到它自己的位置parent.cpp(就像您为 所做的那样child.cpp),以便整个程序中只有一个:

    parent::~parent(){}
    
  • 或者将其保留在标题中,但将其标记为内联,以便允许多个(相同的)定义:

    inline parent::~parent(){}
    

如果函数不是纯虚函数 ( = 0),您还可以选择在声明时直接定义它:

struct A
{
    virtual f() {};
}

// No need for f::f() {}

推荐阅读