C ++运算符重载会影响类内运算符函数

时间:2012-09-12 19:16:15

标签: c++ operator-overloading

如果我重载!=运算符并在其他运算符重载程序中使用class!=,它是否接受非重载或重载会怎么样?我正在尝试创建一个noob_ptr(我正在考虑的一种自定义指针包装器)

class noob_ptr 
 {
      private: //does this change the behaviour? public? protected?
      bool operator!=(noob_ptr x)
       {
         ...
        }
      bool operator,(noob_ptr y)
      {
         ...
         if(y!=z)...
         ...
      }
    ...
      }

以下示例是否取消了我班级中重载运算符的使用?

class noob_ptr 
 {
      protected: //or public
      bool operator,(noob_ptr y) //yes, z is also a noob_ptr
      {
         ...
         if(y!=z)...
         ...
      }
    ...
      private: 
      bool operator!=(noob_ptr x)
       {
         ...
        }
      }

3 个答案:

答案 0 :(得分:1)

如果您提供的操作数是语言的内置!=可以使用的操作数,那么这就是使用的操作数。如果它们是用户定义的类型,那么它将搜索为这些类型定义的用户定义的operator!=(或某些支持从这些类型隐式转换的类型)。

答案 1 :(得分:1)

如果z的类型也是noob_ptr,则答案为是,它会为您的班级调用重载的operator !=。 另外,我建议你使用这种比较方法签名:

bool operator != (const noob_ptr& x) const;

所以它可以用于常量指针,也可以在调用重载操作符时避免对象复制。

UPD :如果您将operator !=声明为私有,那么它将在noob_ptr类的所有成员函数,朋友类和{{1}的函数中可用} class,并且对于所有其他用法将导致编译错误,例如:“operator!=由于其保护级别而无法访问”

答案 2 :(得分:1)

C ++将始终使用最匹配的“最佳匹配”,访问说明符,如私有,范围,命名空间等。

所以,如果有一个全局命名空间运算符!=和一个类(缺少左侧参数,假设是类&或const类&如果方法是const - 它应该be),然后在类(命名空间)中,你将得到类中的那个。

如果全局命名空间和类之间只有一个,那么你显然会得到那个。

以下代码演示了全局范围和类范围。您可以通过添加const限定符等来扩展它。

 #include <iostream>
using namespace std;

// Forward declaration to use without the class definition
class X;

bool operator!=(     int lhs, const X& rhs) {
  cout << "bool operator!=(     int lhs, const X& rhs)" << endl;
  return false;
}
bool operator!=(const X& lhs, const X& rhs) {
  cout << "bool operator!=(const X& lhs, const X& rhs)" << endl;
  return false;
}
bool operator!=(const X& lhs,      int rhs) {
  cout << "bool operator!=(const X& lhs,      int rhs)" << endl;
  return false;
}
// Note: Can't do: bool operator!=(int lhs, int rhs) -- already defined

class X {
private:
  int x;
public:
  X(int value) : x(value) { }

  bool operator !=(const X& rhs) {
    cout << "bool X::operator !=(const X& rhs)" << endl;
    return true;
  }

  bool operator !=(int rhs) {
    cout << "bool X::operator !=(int rhs)" << endl;
    return true;
  }

  void f() {
    X compare(1);
    cout << "X::f()" << endl;
    cout << (5 != 3) << endl;         // Uses built-in
    cout << (*this != 3) << endl;     // Uses member function
    cout << (*this != 1) << endl;     // Uses member function
    cout << (1     != *this) << endl; // There can be no member function, uses global namespace
    cout << (*this != compare) << endl;
  }
};


void f(const X& arg) {
  cout << "f()" << endl;
  X compare(1);
  cout << (5 != 3) << endl;         // Uses built in
  cout << (arg != 3) << endl;       // Uses global namespace
  cout << (arg != 1) << endl;       // Uses global namespace
  cout << (1   != arg) << endl;     // Uses global namespace
  cout << (arg != compare) << endl; // Uses global namespace
}

int main(int argc, char **argv) {
  X x(1);
  x.f();
  f(x);
  return 0;
}