【问题标题】:C++ operator overloading affect in-class operator functionsC++ 运算符重载影响类内运算符函数
【发布时间】:2012-09-12 19:16:15
【问题描述】:

如果我重载!= 运算符并在其他运算符重载器之一中使用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)
       {
         ...
        }
      }

【问题讨论】:

  • 我没有完全理解你的意思,但是按照operator== 来实现operator!= 是很常见的:bool operator!=(const MyClass &lhs, const MyClass &rhs) {return !(lhs == rhs);}
  • 我的意思是在课堂上,我使用了很多重载器。如果使用它们,它们会改变其他重载器的行为吗?
  • 您的问题不清楚。也许您可以发布一个 actual program 来证明您的问题。
  • 请参阅下面的会员访问限制我的回答。简而言之,您第二个问题的答案是否定的。
  • 为什么你需要超载operator,?为他人进行愉快的调试?

标签: c++ operator-overloading


【解决方案1】:

如果z 的类型也是noob_ptr,那么答案是肯定的,它将为您的班级调用重载的operator !=。 另外,我建议你这个比较方法签名:

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

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

UPD:如果您将operator != 声明为私有,那么它将在noob_ptr 类的所有成员函数、朋友类和noob_ptr 类的函数中可用,并且适用于所有其他用法将导致编译错误,并显示如下消息:“operator != is inaccessible due to its protection level”

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我用一些代码更新了这个问题。你说我的重载者是主要目标还是次要目标?
    • @tuğrulbüyükışık: 是的,假设yz 都具有noob_ptr 类型,那么if (y != z) 将使用noob_ptr::operator!=(noob_ptr) 进行比较(如果存在,则为一个全局变量) bool operator!=(noob_ptr a, noob_ptr b);)。
    【解决方案3】:

    C++ 将始终使用在限定符、访问说明符(如私有、范围、命名空间等)中最接近的“最佳匹配”。

    所以,如果有一个全局命名空间 operator!= 和一个类 one(缺少左侧参数,如果方法是 const 则假定为 class& 或 const class& - 它应该是) ,然后在类(命名空间)中,您将获得类中的那个。

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

    以下代码演示了全局作用域和类作用域之间的关系。您可以通过添加 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-26
      • 2023-03-17
      • 2016-02-19
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多