如何避免重写方法的多重定义

How to avoid multiple definition of overridden method

我有一个 Base class 和一个 Derived class(派生自 Base class)。 两个 classes 都有一个名为“getNumber ()”的方法。

在我的 main () 中,我想 运行 Derived class 的方法“getNumber()”。 我的 main 实例化了 Animal class 的一个对象。 在 Animal class 中是成员变量:指向 Base class 的指针,称为“base”。 但是,在 Animal class 的构造函数中,我想将该“基”指针设置为 Derived 类型的对象。

但是,当我尝试编译它时,我收到以下错误消息:

Animal.cc:(.text+0x0): multiple definition of `Derived::getNumber()'; /tmp/ccwfn1zo.o:Derived.cc:(.text+0x0): first defined here
/usr/bin/ld: /tmp/ccwfn1zo.o: in function `Derived::~Derived()':
Derived.cc:(.text._ZN7DerivedD2Ev[_ZN7DerivedD5Ev]+0x26): undefined reference to `Base::~Base()'
/usr/bin/ld: /tmp/ccwfn1zo.o:(.data.rel.ro._ZTI7Derived[_ZTI7Derived]+0x10): undefined reference to `typeinfo for Base'
/usr/bin/ld: /tmp/ccpsXsim.o: in function `Derived::Derived()':
Animal.cc:(.text._ZN7DerivedC2Ev[_ZN7DerivedC5Ev]+0x18): undefined reference to `Base::Base()'
collect2: error: ld returned 1 exit status

这里是主要的:

#include <iostream>
#include "Animal.h"
#include "Base.h"

using namespace std;


int main()
{
    Animal * a = new Animal;
    cout << a->base->getNumber();
}

这里是 Base.h 中基础 class 的代码:

class Base {
public:
    Base ();
    virtual ~Base ();
public:
    virtual unsigned int getNumber() {
        return 1;
    }
};

这里是Derived.cc的代码:

#include "Base.h"

class Derived : public Base {

public:
    ~Derived () {}
    
public:
    unsigned int getNumber () override;
   
};

unsigned int Derived::getNumber () {
    return 5;
}

这里是Animal.h

的代码
class Base;

class Animal {
public:
    Animal ();
    ~Animal ();
  
public:
    Base* base = nullptr;
};

最后 Animal.cc

#include "Animal.h"
#include "Derived.cc"

Animal::Animal () {
    base = new Derived;
}

我做错了什么?我认为这是基本的东西,但我没有看到。

包括像

这样的源文件
#include "Derived.cc"

是一种不好的做法。相反,将应该从多个源文件中看到的所有内容放在头文件中并包含头文件。

在这种情况下,您应该创建一个新的头文件Derived.h并将class Derived的声明移动到头文件中。 函数Derived::getNumber的定义应该保留在Derived.cc.

问题 是您包含了一个名为 Derived.cc 源文件 而不是头文件。这会导致多重定义错误,因为此源文件随后被(直接和间接)包含到其他文件中,因此提到的成员函数 Derived::getNumber().

存在“多重定义”

要解决这个问题,您应该创建一个名为 Derived.h 的头文件,其中包含成员函数的声明,以及一个单独的源文件,其中包含这些成员函数的实现,如下所示。 Working Demo

main.cpp

#include <iostream>
#include "Animal.h"
#include "Base.h"

int main()
{
    Animal * a = new Animal;
    std::cout << a->base->getNumber();
}

Base.h

#include <iostream>
#include "Animal.h"
#include "Base.h"

int main()
{
    Animal * a = new Animal;
    std::cout << a->base->getNumber();
}

Base.cc

#include "Base.h"

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

Animal.h

class Base;

class Animal {
public:
    Animal ();
    ~Animal ();
  
public:
    Base* base = nullptr;
};

Animal.cc

#include "Animal.h"
#include "Derived.h"

Animal::Animal () {
    base = new Derived;
}

Derived.h

#include "Base.h"

class Derived : public Base {

public:
    ~Derived () {}
    
public:
    unsigned int getNumber () override;
   
};


Derived.cc

#include "Derived.h"
unsigned int Derived::getNumber () {
    return 5;
}

Working Demo

注意:我们不应包含源文件。