运算符重载,但仍然"与运算符不匹配"错误
Overloaded operator, but still "no match for operator" error
我有一个重载输出运算符"<<"的类,我已经这样实现了它。但是,编译者抱怨主方法中的"与运算符<<不匹配"。我不知道为什么它不起作用。
/*
* Accumulator.cpp
*
*
*
*/
#include <iostream>
#include "Accumulator.h"
using namespace std;
Accumulator::~Accumulator() {
// TODO Auto-generated destructor stub
}
void Accumulator::operator+=(const int nbr) {
nbrs.push_back(nbr);
}
void Accumulator::undo() {
if (!comitted) {
nbrs.pop_back();
}
}
void Accumulator::commit() {
lastCommit = nbrs;
comitted = true;
}
void Accumulator::rollback() {
nbrs = lastCommit;
}
ostream& Accumulator::operator<<(ostream &out, const Accumulator &accum){
int sum = 0;
for(int nbr : nbrs){
sum+= nbr;
}
out << sum;
return out;
}
int main() {
Accumulator accum;
char cmd;
while (cin >> cmd) {
switch (cmd) {
case 'p':
cout << "Sum is now " << accum << endl;
break;
case 'a': {
int nbr;
cin >> nbr;
accum += nbr;
break;
}
case 'u':
accum.undo();
break;
case 'c':
accum.commit();
break;
case 'r':
accum.rollback();
break;
}
}
}
非静态成员函数始终有一个额外的隐藏参数,即this
指针,即调用函数的对象。假设您有这样的类:
class Test {
public:
void f(int param) {
}
};
Test t;
t.f(10);
调用t.f(10)
基本上等效于后台的类似内容:Test::f(&t, 10)
(请注意,这不是有效的代码,只是为了让您了解会发生什么)。
现在回到你的运算符,如果你把它作为类中的一个成员函数,那么你就不能像往常一样调用它。那是因为这样称呼它:
std::cout << accum;
相当于这个:
cout.operator<<(accum);
在后台相当于这个:
Accumulator::operator<<(&cout, accum);
而您的成员函数等效于以下内容:
ostream& operator<<(Accumulator* this, ostream &out, const Accumulator &accum);
请注意,参数不匹配。
因此,正确重载operator<<
的唯一方法是使其成为自由函数:
class Accumulator {...};
ostream& operator<<(ostream &out, const Accumulator &accum);
这样,像这样的正常调用:
std::cout << accum;
相当于这个:
operator<<(std::cout, accum);
这与重载的声明完全匹配。
如果在重载实现中需要访问Accumulator
类的私有成员,可以通过不同的方式执行此操作:例如,使重载成为类的好友,或者在类中添加一个公共函数,如下所示:
class Accumulator {
public:
void printToStream(ostream &out) const {
out << private_members;
}
};
并从运算符重载调用它,如下所示:
ostream& operator<<(ostream &out, const Accumulator &accum) {
accum.printToStream(out);
return out;
}
现在,您不必再让超载成为类的朋友了。
正如 @n.m. 所建议的,流注入器不能作为成员函数重载,而是作为 2 个参数的普通函数。
您的 .h 文件变为:
class Accumulator {
... // no operator << here !
};
ostream& operator << (ostream &out, const Accumulator& accum);
和实施:
ostream& operator << (ostream &out, const Accumulator& accum) {
...
return out;
}
如果您正在编写自定义ostream
类(例如专用记录器),则只会使用一个参数成员函数重载。
相关文章:
- 在使用累加时,C++中的运算符+不匹配
- 我在 .h 中有一个枚举类,并且在.cpp错误中有一个运算符重载:与"运算符<<不匹配
- 为什么我收到错误:"运算符<<不匹配?
- 映射迭代器与运算符不匹配
- 与"运算符>>"不匹配(操作数类型为"QDataStream"和"QJsonObject")
- 与标准中的"运算符<<"不匹配
- 运算符不匹配*=
- 不断收到错误" 与"运算符>>不匹配";
- 编译我的 3 个文件时,我收到错误,说"运算符="不匹配
- C++ 模板与运算符<不匹配
- 与"运算符="不匹配
- 代码块编译错误与运算符<<不匹配
- 错误:运算符 [] 不匹配。在比较列表中的 int 和 int 时<int>,
- 解决错误:运算符 [] 不匹配
- 错误:与"运算符>>"不匹配(操作数类型为"std::istream
- 与"运算符[]"不匹配(操作数类型为"std::unique_ptr<std::vector<int> >"和"int")
- 错误:与“运算符 []”不匹配
- 与"运算符<<不匹配
- 错误:与"运算符[]"不匹配(操作数类型为"QVector<int>"和"QCharRef")
- 错误:"运算符>>"不匹配 重载 istream 运算符