我正在做一个关于C ++的教程,真正深入研究它的细节,因为坦率地说它是一种非常强大的语言。虽然我还是比较陌生,但是我的运算符重载为ostream运算符时遇到了问题。
由于这是一个教程,我试图尽可能保持我的代码有序和模块化,以避免混淆。我的代码有3层:
Main非常简单:对Exercises :: ExerciseName()的调用。
Exercises.cpp:
#include "Exercises.h"
void Exercises::ComplexNumberClass() {
ComplexNumber c; /** Runs the blank constructor */
ComplexNumber c1(2, 3); /** Runs the args-filled constructor */
ComplexNumber c2 = c1; /** Runs the copy constructor */
c = c2;
cout << c1 << endl;
}
头文件只有该函数的头部作为公共静态void函数,即可调用和可执行。 ComplexNumber文件是我认为问题所在(如果我错了,请纠正我):
ComplexNumber.cpp(没有构造函数和访问器):
#include "ComplexNumber.h"
using namespace ComplexNumbers;
using namespace std;
ostream& operator<< (ostream& out, ComplexNumber& num){
out << "(" << num.GetReal() << ", " << num.GetImaginary() << ")";
return out;
}
const ComplexNumber &ComplexNumber::operator=(const ComplexNumber &num) {
cout << "Using assignment operator override" << endl;
real = num.real;
imaginary = num.imaginary;
return *this;
}
ComplexNumber.h:
#ifndef OPERATOROVERLOADING_COMPLEXNUMBER_H
#define OPERATOROVERLOADING_COMPLEXNUMBER_H
#include <iostream>
using namespace std;
namespace ComplexNumbers {
class ComplexNumber {
private:
double real;
double imaginary;
public:
ComplexNumber();
ComplexNumber(double real, double imaginary);
ComplexNumber(const ComplexNumber &num);
const ComplexNumber &operator=(const ComplexNumber &num);
double GetReal() const {
return real;
}
double GetImaginary() const {
return imaginary;
}
};
ostream &operator<<(ostream& out, ComplexNumber& num);
}
#endif //OPERATOROVERLOADING_COMPLEXNUMBER_H
当我建立这个时,它告诉我,我有一个&#34;未定义的引用'cave_of_programming :: operator&lt;&lt;(std :: ostream&amp;,cave_of_programming :: ComplexNumber&amp;) &#39 ;.方法标题匹配,我与Jetbrains CLion建立。
我的研究表明问题出现在链接器中,但我查看了我的CMakeLists.txt,发现它正在连接所有相应的文件。
SOURCE_FILES main.cpp Exercises.cpp Exercises.h ComplexNumbers/ComplexNumber.cpp ComplexNumbers/ComplexNumber.h
有没有人知道为什么这不起作用?我错过了什么?
答案 0 :(得分:2)
问题是你在课堂上定义了ostream &operator<<(ostream& out, ComplexNumber& num)
。这对编译器没有多大意义,因为它知道在获取ostream对象和某种类型的类时覆盖operator<<
,
但是你实现它的方式,它得到了ostream,一个ComplexNumber,另一个ComplexNumber作为'this'引用。
为了正确地重载二元运算符,您有两个选择:
在类中定义运算符,并仅将ostream作为参数
class ComplexNumber
{
...
ostream &operator<<(ostream& out) const;
};
或者在类外部定义运算符并为其提供两个参数:
class ComplexNumber
{
...
};
ostream &operator<<(ostream& out, const ComplexNumber& num);
请注意,在第二个实现中,如果要访问任何私有成员,则需要将该函数添加为该类的朋友。
另请注意,在这里使用const是个好主意,就像我在示例中一样,否则你将无法在const ComplexNumbers上使用运算符。