这可以在不使用朋友的情况下完成吗

Can this be done without using friends?

本文关键字:情况下 朋友      更新时间:2023-10-16

以下代码(我只保留了相关部分)是否可以转换为使用静态成员函数而不是无友函数?如果没有,为什么不呢?我试图以多种不同的方式将其转换为使用静态成员函数,但都失败了(针对不同的变体,不断出现不同的编译器错误),但我从这个问题的答案中了解到,你可以使用其中任何一种来做同样的事情。由于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;
}

根据C++标准

6操作员功能应为非静态成员功能,或是非成员函数,并且至少有一个参数的类型为类、对类的引用、枚举或对枚举。

因此,您可能不会将operator <<定义为类的静态主函数。然而,在运算符的定义中,您可以使用静态成员函数。例如

#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++相反,运算符函数被定义为静态。:)

由于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;
}