遵循一个定义规则,但C++抛出重新定义错误

C++ 中非常奇怪的重定义错误,特别是因为包括 main 在内的所有其他文件都没有错误。

我有我的标题(各种动物)和一个实现文件“animals.cpp”。

我的标题遵循以下格式:

class Mammal : public Animal{
    public:
        Mammal(){} //empty constructor
        virtual ~Mammal(){} // destructor
        void createNewMammalObject(std::string name, std::string trackingNum, std::string nurse, std::string subType, std::string type){}
        std::string getSubtype() {}
        void setSubtype(std::string subType){}
        int getNursing(){}
        void setNursing(int nursing){}
        void setType(std::string type){}
        int getNumEggs(){}

    protected:
        int nursing;
};

实现文件中的实现如下所示:

Mammal::Mammal() {} //empty constructor

virtual Mammal::~Mammal(){} // destructor

void Mammal::createNewMammalObject(std::string name, std::string code,std::string nurse,std::string subType, std::string type){
    this->setNursing(nursing);
    this->setSubType(subType);
    this->createNewAnimalObject(name, trackingNum,subType,type);
}

std::string Mammal::getSubtype() {
    return subType;
}

void Mammal::setSubtype(std::string subType) {
    this->subType = subType;
}

int Mammal::getNursing() {
    return this->nursing;
}

void Mammal::setNursing(int nursing) {
    this->nursing = nursing;
}

void Mammal::setType(std::string type){
    this->type = type;
}

int Mammal::getNumEggs() {
    return 0;
}

我的#includes 实现文件是:

#include "animal.h"
#include "oviparous.h"
#include "mammal.h"
#include "crocodile.h"
#include "goose.h"
#include "pelican.h"
#include "bat.h"
#include "seaLion.h"
#include "whale.h"

所有头文件和实现都遵循这种格式以遵循 One-Definition,除了animal.h 是一个抽象类并且确实包含函数定义。所有其他函数肯定只定义一次。但是,在构建项目之后,实现文件中的每个函数都说这是一个重新定义并指向作为原始定义的头文件。我非常困惑。这是 Eclipse 的问题吗?我的抽象类是否应该像其他标题一样在我的实现文件中定义?

回答

关于你的头文件(集中于一个线,但他们几乎全都有同样的问题):

std::string getSubtype() {}
//                       ^^
//                    see here

这是一个定义一个空体功能的,非定义声明将是:

std::string getSubtype();

您在头文件实现文件中都定义函数这一事实几乎肯定是您违反 ODR 的原因。

还有另外两点,不一定是致命的:


首先,这是正常设置的基类的东西使派生类可以覆盖特定的属性。这将导致重新排序(在修复护士/护理差异之后):

#include <string>

void Mammal::createNewMammalObject(
    std::string name,
    std::string code,
    std::string subType,
    std::string type,
    std::string nursing  // moved to end, just a foible of mine.
) {
    this->createNewAnimalObject(name, trackingNum, subType, type);
    // Could now modify below any of those items in previous line.

    this->setNursing(nursing);
    this->setSubType(subType);
}

其次,构造函数通常会做尽可能多的工作,而不是让某些函数进行设置。后者导致如果您忘记调用该函数,则构造的对象可能处于某种奇怪的不可用状态。

我会更多地关注以下方面:

#include <string>

class Animal {
public:
    Animal(
        std::string name,
        std::string trackingNum,
        std::string subType,
        std::string type
    )
    :   m_name(name)
    ,   m_trackingNum(trackingNum)
    ,   m_subType(subType)
    ,   m_type(type)
    {
        // Other less important initialisation and possibly also
        // throwing exception if any of those four above are invalid.
    }
private:
    std::string m_name;
    std::string m_trackingNum;
    std::string m_subType;
    std::string m_type;
};

class Mammal :Animal {
public:
    Mammal(
        std::string name,
        std::string trackingNum,
        std::string subType,
        std::string type,
        std::string nursing
    )
    :   Animal(name, trackingNum, subType, type)
    ,   m_nursing(nursing)
    {
        // Ditto on more initialisation and throwing
        // for bad nursing value.
    }
private:
    unsigned int m_nursing;
};

int main() {}


以上是遵循一个定义规则,但C++抛出重新定义错误的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>