【问题标题】:Scope operator in Operator Overloading运算符重载中的范围运算符
【发布时间】:2019-09-19 12:21:22
【问题描述】:

我无法理解运算符重载中的范围运算符。当他们不使用它时,有一些例子。当我应该写T::operator.时我可以只写操作符仍然可以正常工作还是建议使用::?

例子:


原型示例(用于 T 类) 内部类定义

T& T::operator +=(const T2& b){}

我可以写成T& operator +=(const T2& b){} 还是我应该一直写成T& T::operator +=(const T2& b){}

【问题讨论】:

  • 如果你将定义放在一个类中,你不需要告诉编译器它属于哪个类。如果你在类之外定义它,编译器没有任何线索,除非你通过T::明确告诉它。
  • 你问什么时候需要T::name_of_member_function
  • "operator +=" 只是一个时髦的名字。在声明和定义中,它的工作方式与任何其他函数完全相同。
  • @NathanOliver T::operator +=
  • 你能提供一个minimal reproducible example吗?

标签: c++ oop operator-overloading scope-resolution-operator


【解决方案1】:

运算符+= 可以声明为类或类模板的成员函数或成员模板,并在类或类模板内部或外部定义。

如果在类外定义,则需要范围运算符。

操作符也可以被声明和定义为一个独立的非类函数

考虑以下演示程序

#include <iostream>

struct A
{
    int x = 0;

    A & operator +=( char c )
    {
        x += c;
        return *this;
    }
};

struct B
{
    int x = 0;

    B & operator +=( char c );
};

B & B::operator +=( char c )
{
    x += c;
    return *this;
}

struct C
{
    int x = 0;
};

C & operator +=( C & cls, char c )
{
    cls.x += c;

    return cls;
}

int main() 
{
    A a;

    a += 'A';

    std::cout << "a.x = " << a.x << '\n';

    B b;

    b += 'B';

    std::cout << "b.x = " << b.x << '\n';

    C c;

    c += 'C';

    std::cout << "c.x = " << c.x << '\n';

    return 0;
}

它的输出是

a.x = 65
b.x = 66
c.x = 67

运算符也可以声明为模板运算符。例如

#include <iostream>

template <class T>
struct A
{
    T x = T();
};    

template <class T1, class T2>
T1 & operator +=( T1 &a, const T2 &x ) /* C++ 17 only requires requires( T1 t ) { t.x; }*/  
{
    a.x += x;
    return a;
}        

int main()
{

    A<int> a;
    std::cout << ( a += 10u ).x << '\n';
}    

同样,如果运算符是成员函数模板并且在其类之外定义,则需要范围解析运算符。

#include <iostream>

template <class T1>
struct A
{
    T1 x = T1();
    template <class T2>
    A<T1> & operator +=( const T2 &x );
};    

template <class T1>
template <class T2>
A<T1> & A<T1>::operator +=( const T2 &x )
{
    this->x += x;
    return *this;
}        

int main()
{

    A<int> a;
    std::cout << ( a += 10u ).x << '\n';
}    

【讨论】:

    【解决方案2】:

    在类内部,不要使用范围解析运算符::

    class T {
    public:
        // ...
        T operator+=(const T2& b)
        {
            // ...
        }
    };
    

    如果在类外定义运算符,则在类外定义中使用范围解析运算符::。您仍然在声明中省略它:

    class T {
    public:
        // ...
        T operator+=(const T2& b);
    };
    
    // in the implementation
    T T::operator+=(const T2& b)
    {
        // ...
    }
    

    这与推荐或良好做法无关。这里所说的一切都是唯一可行的方法,其他方法都不是正确的 C++ 代码。

    【讨论】:

    • 我正在阅读运营商的文档。所以我很困惑,谢谢你的解释,它对我帮助很大!我应该将 T 与 T&operaotr 之类的引用一起使用,还是仅使用 T 运算符?
    • @Hunali 通常复合赋值运算符,如 += 或 -= 返回对 *this 的引用。
    猜你喜欢
    • 2014-03-26
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 2011-01-21
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多