C ++:在2个不同的类中重载相同的运算符时出现问题

时间:2011-01-30 17:02:18

标签: c++ namespaces include operator-overloading

首先非常感谢你的线索。

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

关键在于:我需要两个不同的类(比如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文件中实现。

3 个答案:

答案 0 :(得分:2)

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

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,则需要声明friend运算符。但是,由于这些是您的类,因此最好将运算符声明为成员:

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&)来说,这绝对没必要。

答案 1 :(得分:1)

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

您有两种可能性:

  • anyfile.h
  • 中删除#pragma once /* ... the rest of your code ... */
  • 使用包括这样的警卫:

#pragma once

myheader.h

在你的编译器不支持#ifndef MYHEADER_H #define MYHEADER_H /* ... your code here ... */ #endif 指令的情况下你总是可以使用标准,虽然你的标题中有一些麻烦的宏观守卫:

{{1}}:

{{1}}

答案 2 :(得分:1)

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

答案很长: 当一个函数被声明为friend时,它意味着它不属于它被“声明”的类(事实上,你没有在那里声明函数),你只是说该函数(注意它将是

您可能正在使用朋友,因为您看到了使用该代码的运算符<< (使用std :: ostream),但这不能成为因为你需要成为std :: ostream的成员函数。删除朋友,你将使“这个”成为第一个操作员。