Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:在两个不同的类中重载同一运算符时出现问题_C++_Namespaces_Include_Operator Overloading - Fatal编程技术网

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

C++ C++;:在两个不同的类中重载同一运算符时出现问题,c++,namespaces,include,operator-overloading,C++,Namespaces,Include,Operator Overloading,首先非常感谢你提供的线索 我在完成作业时遇到了一个特殊的问题。我很确定名称空间、包括、头文件和所有这些东西都有问题,但我真的不知道出了什么问题 重点是:我需要两个不同的类(比如Car和CarShop),每个类都必须使操作员过载+ Car->Car&operator+(const Car&c)(应“添加”两辆车) CarShop->CarShop&operator+(const Car&c)(应将汽车“添加”到现有的CarShop) 在文件CarShop.h中,我需要#包括“car.h”,因为

首先非常感谢你提供的线索

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

重点是:我需要两个不同的类(比如
Car
CarShop
),每个类都必须使操作员过载+

  • Car
    ->
    Car&operator+(const Car&c)
    (应“添加”两辆车)
  • CarShop
    ->
    CarShop&operator+(const Car&c)
    (应将汽车“添加”到现有的CarShop)
在文件
CarShop.h
中,我需要
#包括“car.h”
,因为它与不同的“car”对象一起工作。此外,在我的主要测试类中,比如说
main.cpp
,我还需要
#包括“car.h”
#包括“carshop.h”

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

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


这两个操作符(2个重载操作符)都被声明为各自类的友元函数(在.h文件中),并在各自的.cpp文件中实现。

您正在成倍地声明一个汽车类型。在您的
main.cpp
中包括
car.h
carshop.h
,而
carshop.h
已经包括
car.h
。如果没有包含保护,则会导致链接器错误

你有两种可能:

  • main.cpp中删除
    #包括“Car.h”
  • 使用包括这样的防护装置:
anyfile.h

#pragma once

/* ... the rest of your code ... */
#ifndef MYHEADER_H
#define MYHEADER_H

/* ... your code here ... */

#endif
如果您的编译器不支持
#pragma once
指令,您可以始终在标题中使用标准的宏保护,尽管有点麻烦:

myheader.h

#pragma once

/* ... the rest of your code ... */
#ifndef MYHEADER_H
#define MYHEADER_H

/* ... your code here ... */

#endif

您正在声明一种汽车类型。在您的
main.cpp
中包括
car.h
carshop.h
,而
carshop.h
已经包括
car.h
。如果没有包含保护,则会导致链接器错误

你有两种可能:

  • main.cpp中删除
    #包括“Car.h”
  • 使用包括这样的防护装置:
anyfile.h

#pragma once

/* ... the rest of your code ... */
#ifndef MYHEADER_H
#define MYHEADER_H

/* ... your code here ... */

#endif
如果您的编译器不支持
#pragma once
指令,您可以始终在标题中使用标准的宏保护,尽管有点麻烦:

myheader.h

#pragma once

/* ... the rest of your code ... */
#ifndef MYHEADER_H
#define MYHEADER_H

/* ... your code here ... */

#endif

简短回答:不要将这些操作符声明为好友

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


您可能正在使用friend,因为您看到代码将其用于运算符简短回答:不要将这些运算符声明为friend

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


您可能正在使用friend,因为您看到的代码将其用于运算符,正如其他人所指出的,您不能仅将其声明为friend:

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

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

正如其他人所指出的,你不能仅仅把他们宣布为朋友:

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
不需要