c++ - 在父类(super class)中重载运算符,但子类声称它已经定义

标签 c++ visual-c++

我正在学习 C++,我不太清楚继承和运算符重载的工作原理,所以我很可能会在这里做一些愚蠢的事情。

我有一个基类,它定义了一些非常基本的操作来表示测量单位:

#pragma once
class UnitOfMeasure
{
public:
    UnitOfMeasure(void) : mAmount(0) {}
    UnitOfMeasure(double amount) : mAmount(amount) { }
    ~UnitOfMeasure() {}

    void SetAmount(double amount) { mAmount = amount; }

    UnitOfMeasure& operator+=(const UnitOfMeasure& rhs)
    {
        mAmount += rhs.mAmount;
        return *this;
    }

    friend bool operator==(const UnitOfMeasure&, const UnitOfMeasure&);

protected:
    double mAmount;
};

bool operator==(const UnitOfMeasure& lhs, const UnitOfMeasure &rhs)
{
    return rhs.mAmount == lhs.mAmount;
}

子类然后像这样实现特定的转换:

#pragma once
#include "UnitOfMeasure.h"

class Temperature : public UnitOfMeasure
{
public:
    enum TemperatureUnit { CELSIUS, FAHRENHEIT };
    Temperature(void) { }
    Temperature(double amount, TemperatureUnit units=CELSIUS) { SetAmount(amount, units); }
    ~Temperature(void) {};
    void SetAmount(double amount, TemperatureUnit units=CELSIUS)
    {
        switch(units)
        {
            case CELSIUS: { mAmount = amount; break; }
            case FAHRENHEIT: { mAmount = (amount - 32) / 1.8; break; }
        }
    }
    double Fahrenheit() { return 32 + (mAmount * 1.8); }
    double Celsius() { return mAmount; };
};

在我的示例程序中,我将 Temperature 的实例存储在一个列表中,这就是事情开始变得奇怪的地方。当所有代码都包含在 .h 文件中时,一切都很好。我可以编译并运行成功。但是,当我将 Temperature 的代码分解为单独的 .cpp 文件时,编译器会报错。我收到这些消息:

1>  Temperature.cpp
1>Temperature.obj : error LNK2005: "bool __cdecl operator==(class UnitOfMeasure const &,class UnitOfMeasure const &)" (??8@YA_NABVUnitOfMeasure@@0@Z) already defined in BadComparison.obj
1> BadComparison.exe : fatal error LNK1169: one or more multiply defined symbols found

(我使用的是 Visual Studio 2012)

编译器是否为我的 Temperature 类创建了一个单独的 == 运算符?

谢谢!

最佳答案

您应该将您的运算符声明为inline 以避免其定义成为#include 相应头文件的多个翻译单元的一部分:

    inline bool operator==(const UnitOfMeasure& lhs, const UnitOfMeasure &rhs)
//  ^^^^^^
    {
        return rhs.mAmount == lhs.mAmount;
    }

在这种情况下,链接器最终会提示同一函数在您的程序中被多次定义,这违反了 One Definition Rule .

关于c++ - 在父类(super class)中重载运算符,但子类声称它已经定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15512612/

相关文章:

c++ - 子对象作为参数

c++ - 删除标准列表中的指针对象

c++ - 如何使用fprintf将连续的512字节保存到文件中

visual-c++ - 要求对 VC++ 进行有关插入和安放的调查

c++ - 向后迭代 std::array 或 std::vector 的正确方法是什么?

c++ - 编写将二进制转换为文本的程序 c++6

c++ - 静态链接到 libzbar.a 时出错 : undefined reference to `_imp__GetACP@0'

c++ - 比较对 int 和 unsigned 的引用时发出警告,但如果将 const(无引用)与 g++/msvc 进行比较则没有警告

c# - 从 C++ 到 C# 的编码

c++ - 严重错误C1083