当尝试重载运算符==时,如何比较两个类的私有变量?

3

我正在尝试重新创建字符串类,在将两个类相互比较时遇到了麻烦,就像它们是字符串一样进行比较。这是我在头文件中的内容:

class Mystring {
public:
   // ...
private:
    // this variable stores the memory address of the text
    char* ptr_buffer

    // ...
};

在源文件中,我有如下代码:
bool operator== (const Mystring& a, const Mystring& b) {
    return a.ptr_buffer == b.ptr_buffer;
}

但是出于某种原因,当我尝试在main.cpp中比较两个Mystring类时,它会显示无法访问私有变量ptr_buffer。我以为它有权访问那个变量?如果我只关心比较隐藏属性,我该如何比较这两个类呢?


{btsdaf} - PaulMcKenzie
1
{btsdaf} - mnistic
1个回答

1
从C++语言的角度来看,引入到全局作用域的重载运算符就像全局作用域下的任何其他函数一样(除了它自定义了内置运算符的工作方式)。正如常规的自由函数不能访问类的私有字段一样,自由函数重载运算符也不能访问它要重载运算符的类的私有字段。
这样做有很好的理由。例如,自定义类通常会将operator<<重载为一个参数是ostream引用,另一个参数是自定义类型。如果这个自定义重载可以访问ostream类型的字段,那就非常糟糕!
你在类的实现文件中定义operator==的事实也是无关紧要的。尽管通常是这样实现类的,但C++没有类的“实现文件”的概念。它在这方面将所有源文件视为平等的。
要解决这个问题,您可以将operator==函数声明为类的友元:
class MyString {
public:
     ...
     friend bool operator== (const MyString& lhs, const MyString& rhs);
}

...

bool operator== (const MyString& lhs, const MyString& rhs) {
    // You were given explicit authorization to access private fields,
    // so go right ahead!
}

然而,你确定你的operator ==实现是正确的吗?你比较的是MyString对象中存储的指针,而不是它们所指向的字符串内容。如果你在内存中有两个相同的字符串文字副本,你可能会有两个逻辑上相等(它们表示相同的字符串)但不相等的MyString

事实上,你可能想问一个单独的问题:你能使用MyString类型的公共接口来实现operator==吗?在一个好的字符串类型中,答案应该是“是的”,因为你应该能够按顺序访问字符并查看长度。从效率的角度来看,这不是理想的,但这是一个很好的测试,以查看接口是否良好。因此,你可以尝试实现这个函数,不使用私有字段来确保你可以,然后考虑将operator ==作为friend的好处以及从性能角度来看是否是一个好主意。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接