可以将以下代码(我只保留相关部分)转换为使用静态成员函数而不是朋友免费函数吗?如果没有,为什么不呢?我尝试将它转换为以多种不同的方式使用静态成员函数并失败(不同变体的编译器错误不同),但我从this question的答案收集到你可以使用其中任何一个来做同样的事情的东西。由于C ++语法的某些属性,这在技术上是否正确?我在哪里错了?
class Tape {
public:
friend std::ostream &operator<<(std::ostream &, Tape &);
private:
char blank;
size_t head;
std::string tape;
}
std::ostream &operator<<(std::ostream &out, Tape &tape) {
out << tape.tape << std::endl;
for (size_t i = 0; i < tape.head; i++)
out << ' ';
out << '^' << std::endl;
return out;
}
答案 0 :(得分:1)
根据C ++标准
6运算符函数应该是非静态成员函数或 是非成员函数,并且至少有一个类型为的参数 类,对类的引用,枚举或对引用的引用 枚举。
因此,您可能无法将operator <<
定义为类的静态mamber函数。
然而,在运算符的定义中,您可以使用静态成员函数。
例如
#include <iostream>
class A
{
private:
int x = 10;
public:
static std::ostream & out( std::ostream &os, const A &a )
{
return ( os << a.x );
}
};
std::ostream & operator <<( std::ostream &os, const A &a )
{
return ( A::out( os, a ) );
}
int main()
{
A a;
std::cout << a << std::endl;
return 0;
}
与C ++中的C ++相反,操作符函数定义为static。:)
答案 1 :(得分:1)
由于std::ostream
参数是运算符的左侧,因此它不能是您的类的成员(静态或其他)。
因此,它必须是免费功能,因为您无法将成员添加到std::ostream
。
它不一定是朋友,但它可以改为呼叫公共成员。
我个人更喜欢这种方法,因为它不会向外界暴露任何东西。
class Tape {
public:
void print(std::ostream &out) const
{
out << tape << std::endl;
for (size_t i = 0; i < head; i++)
out << ' ';
out << '^' << std::endl;
}
};
std::ostream& operator<<(std::ostream &out, const Tape &tape)
{
tape.print(out);
return out;
}