【问题标题】:C++: Problem while overloading same operator in 2 different classesC++:在 2 个不同的类中重载相同的运算符时出现问题
【发布时间】:2011-01-30 17:02:17
【问题描述】:

首先非常感谢您提供的线索。

我在尝试完成作业时遇到了一个特殊问题。我很确定命名空间、包含、头文件和所有这些东西都有问题,但我真的不知道出了什么问题。

重点是:我需要两个不同的类(比如说CarCarShop),它们中的每一个都必须重载运算符 +。

  • Car -> Car &operator+(const Car &c)(应该“添加”两辆车)
  • CarShop -> CarShop &operator+(const Car &c)(应该将汽车“添加”到现有的 CarShop)

在文件CarShop.h 中,我需要#include "car.h",因为它适用于不同的“汽车”对象。此外,在我的主要测试类中,比如说main.cpp,我还需要#include "car.h"#include "carshop.h"

我在这里收到错误消息。 Visual Studio(我们正在使用它作为我们的 IDE)给我“LNK1169 & LNK2005”错误,解释说“同时定义了一个或多个符号”。

有人可以帮帮我吗?为了避免这两个重载运算符之间的冲突,我应该怎么做?

PS。它们(2 个重载的运算符)都被声明为它们各自类的友元函数(在 .h 文件中),并在各自的 .cpp 文件中实现。

【问题讨论】:

  • (1) 请发布您的代码;如果没有看到导致错误的代码,则很难诊断错误。 (2)“加两辆车”是什么意思? (3) 你的operator+ 应该按值返回,而不是按引用返回,如果它遵循内置+ 的行为:它不应该改变它的任何一个操作数并且应该返回一个新对象。如果你想改变其中一个操作数,你应该考虑使用operator+=
  • 你的.h文件有#define保护吗?
  • 您的问题存在不一致之处:您显示的函数声明是针对成员函数运算符重载的,但随后您说重载“被声明为友元函数”。是哪个?

标签: c++ namespaces include operator-overloading


【解决方案1】:

正如其他人所指出的,您不能只将这些声明为朋友:

Car &operator+(const Car &c);
CarShop &operator+(const Car &c);

即使你可以编译和链接它,它也行不通。而且您无法链接,因为它们具有相同的签名(返回类型不包含在签名中)。你有两个选择:要么有非成员朋友,要么有成员函数(不需要朋友声明)。如果你想要非会员朋友,你应该像这样声明他们,指定两个操作数:

Car operator+(const Car &c1, const Car &c2);
CarShop operator+(const CarShop &cs, const Car &c);

请注意,正如 James 所指出的,这些运算符不应返回引用。它们根据定义返回新实例。

但是,只有当第一个参数的类型与您控制的任何类不同时,才需要使用友元运算符。例如,如果第一个参数的类型为 std::string 或 int,则必须声明友元运算符。但是,由于这些是您的类,您最好将运算符声明为成员:

Car operator+(const Car &c2); // this is declared inside the Car class
CarShop operator+(const Car &c); // this is declared inside the CarShop class

这里不需要朋友,因为他们是会员。好吧,严格来说,如果您想访问 Car 的私有成员,您可能希望将 CarShop::operator+(const Car&) 声明为 Car 类中的朋友。但对于Car::operator+(const Car&),这是绝对没有必要的。

【讨论】:

    【解决方案2】:

    您正在多次声明 Car 类型。在您的main.cpp 中包含car.hcarshop.h,而carshop.h 已经包含car.h。如果没有包含保护,这会导致链接器错误。

    你有两种可能:

    • 从您的main.cpp 中删除#include "Car.h"
    • 像这样使用包含防护:

    anyfile.h:

    #pragma once
    
    /* ... the rest of your code ... */
    

    万一你的编译器不支持#pragma once 指令,你可以随时使用标准,虽然有点麻烦,头文件中的宏保护:

    myheader.h:

    #ifndef MYHEADER_H
    #define MYHEADER_H
    
    /* ... your code here ... */
    
    #endif
    

    【讨论】:

    • 错误信息似乎表明链接错误,所以他可能已经这样做了。
    【解决方案3】:

    简短回答:不要将这些运算符声明为朋友。

    长答案: 当一个函数被声明为友元时,这意味着它不属于它被“声明”的类(实际上,你并没有在那里声明函数),你只是说这个函数(注意它将是C 函数,而不是成员函数)是该类的朋友,可以访问私有数据。

    您可能正在使用friend,因为您看到了使用操作符

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 2021-10-02
      相关资源
      最近更新 更多