重载输入/输出运算符,为什么它以这种方式工作而不是以另一种方式工作
Overloading input/output operators, why does it work this one way vs this other?
问题:我收到了关于这两个运算符的链接器错误。更具体地说,这里有确切的错误消息:
注意:我有一个"工作解决方案",如果你读到底部,我会提到它。我不知道为什么它是这样工作的,而不是这样。我更喜欢这个方法,因为它看起来更干净,没有输入/输出操作符挂在我的声明上方。抱歉太长了。我去掉了一些不必要的东西,比如我现有的其他超负荷运营商,因为它们不相关。
poly.obj : error LNK2005: "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Poly &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAVPoly@@@Z) already defined in lab1.obj
1>poly.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Poly const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVPoly@@@Z) already defined in lab1.obj
1>d:... fatal error LNK1169: one or more multiply defined symbols found
在我的.h文件中(如下所示),我将两个所需的操作符都声明为好友,这样他们就可以访问私人成员。我也把它们作为非会员功能,这就是运营商在这个网站上超载的"指南"所说的正确做法。运算符>>不完整,但这与此无关。我有一个想法,这可能与以下事实有关:在两个地方我有"#include iostream",并且由于.cpp包含.h,所以它会因此而失败吗?不确定这是否是一种正确的预感。这是完整的.h文件:
//file poly.h
#ifndef POLY_H
#define POLY_H
#include <iostream>
using namespace std;
class Poly {
public:
Poly(int = 0, int = 0); //default constructor
Poly(const Poly &); //copy constructor
~Poly(); //destructor
friend ostream& operator<<(ostream& output, const Poly& thePoly);
friend istream& operator>>(istream& input, Poly& thePoly);
private:
int* polynomial;
int maxExponent;
};
istream& operator>>(istream& input, Poly& thePoly) {
return input;
}
ostream& operator<<(ostream& output, const Poly& thePoly) {
bool isZero = true;
for (int i = thePoly.maxExponent; i > 0; i--) {
if (thePoly.polynomial[i] != 0) {
if (thePoly.polynomial[i] < 0) {
output << " -";
}
else {
output << " +";
}
output << thePoly.polynomial[i];
if (i != 0) {
output << "x";
}
if (i != 1) {
output << "^";
}
output << i;
isZero = false;
}
}
if (isZero) {
output << " 0";
}
return output;
}
#endif
以下是链接错误中引用的辅助文件:
// DO NOT change anything in this file. Your code must compile and give the
// correct output with this main on the linux machines.
// Make sure the file containing the member function source is: poly.cpp
// Use all lowercase in the file names.
// This main does not do a thorough job of testing. When testing arrays,
// be sure to test the middle and also all the boundary conditions. Test
// values on the boundary and outside the boundaries, i.e., too big/small.
#include "poly.h"
#include <iostream>
using namespace std;
int main() {
Poly A(5, 7), B(3, 4), C(2), D(A), X, Y;
Poly A2, B2, Z1, Z2;
// set polynomials A and B to desired values
// A = +5x^7 -4x^3 +10x -2
// B = +3x^4 +1x^3
cout << "Enter terms for polynomial A. Enter a coefficient " << endl
<< "then exponent for each term. Enter -1 -1 to terminate." << endl;
cin >> A; // or use a bunch of setCoeff
cout << "Enter terms for polynomial B. Enter a coefficient " << endl
<< "then exponent for each term. Enter -1 -1 to terminate." << endl;
cin >> B; // or use a bunch of setCoeff
// outputs exactly what is in quotes: "A = +5x^7 -4x^3 +10x -2"
cout << "A =" << A << endl;
// outputs exactly what is in quotes: "B = +3x^4 +1x^3"
cout << "B =" << B << endl << endl;
return 0;
}
奇怪的是(至少对我来说),如果我放弃声明,将整个函数移到公共声明之上,但仍然在类中,那么程序就会正确编译为什么是这样???。。。当然,我还没能测试这种编译是否意味着它能正常工作,因为我需要完成操作符>>,这样我才能输入数据,然后输出。
这就是我所说的上述变化:
#ifndef POLY_H
#define POLY_H
#include <iostream>
using namespace std;
class Poly {
friend istream& operator>>(istream& input, Poly& thePoly) {
return input;
}
friend ostream& operator<<(ostream& output, const Poly& thePoly) {
bool isZero = true;
for (int i = thePoly.maxExponent; i > 0; i--) {
if (thePoly.polynomial[i] != 0) {
if (thePoly.polynomial[i] < 0) {
output << " -";
}
else {
output << " +";
}
output << thePoly.polynomial[i];
if (i != 0) {
output << "x";
}
if (i != 1) {
output << "^";
}
output << i;
isZero = false;
}
}
if (isZero) {
output << " 0";
}
return output;
}
public:
Poly(int = 0, int = 0); //default constructor
Poly(const Poly &); //copy constructor
~Poly(); //destructor
private:
int* polynomial;
int maxExponent;
};
#endif
(从注释开始)
如果在头中写入自由函数的主体(如运算符<<),则必须将其标记为内联,否则将违反ODR,并导致您看到的结果(通常是链接器错误)。
相关文章:
- 在 Eclipse 中添加库的工作方式是否与在 Visual Studio 中相同?
- OpenGL应用程序在不同的计算机上的工作方式不同
- 为什么我的代码在添加不相关的代码行后工作方式不同?
- wait_until在主线程而不是主线程中的工作方式不同吗? c ++
- 用于了解输入和输出流缓冲区实际工作方式的程序
- 查找函数在unordered_map中的工作方式是搜索键值
- 尝试使用 Qt 库中的 QPixmap 将图像拆分为多个块。关于他的复制方法的工作方式,我有什么不明白的吗?
- 容器类别在STL中的工作方式
- Unity 的 HLSL/Cg 预处理器工作方式错误?
- 无法让我了解 cin.get 和 cout 在这里的工作方式
- 不了解C 集合的工作方式
- 有人可以解释C 操作员=此处的工作方式
- 了解 declval 在copy_assignment情况下的工作方式
- 打开文件的正确模式是什么,以便 seekp() 的工作方式与在默认模式下打开的文件相同
- 了解文件页在技术级别的工作方式
- 战俘的工作方式不同,详细解释
- 切换到新编译器后,SSCANF 的工作方式有所不同
- 为什么三元运算符在编译时的工作方式与运行时不同?
- 对运算符删除覆盖的工作方式感到困惑
- 在两种情况下,铸造的工作方式不同