繁体   English   中英

使用没有引用参数名称的类重载复制赋值运算符

[英]overloading copy assignment operator with classes without a reference parameter name

我想问一个关于 C++ 中的运算符重载的问题。

我是 C++ 的初学者,一直在学习 OOP。

考虑以下重载的复制赋值运算符:

class Base {
private:
    int value;
public:
    Base () : value {0} 
    {
        cout << "Base No-args constructor" << endl; 
    }
    Base (int x) : value {x} {
        cout << "Base (int) overloaded constructor" << endl;
    }
    Base (const Base &other) : value {other.value} {
        cout << "Base copy constructor" << endl;
    }
    Base & operator = (const Base &rhs) {
        cout << "Base operator=" << endl;
        if (this == &rhs)
            return *this;
        value = rhs.value;
        return *this;
    }

    ~ Base () {cout << "Base Destructor" << endl;}
};

我想澄清两点。

  1. 这个复制赋值运算符是如何工作的?
  2. operator 关键字之前的引用是否需要参数名称?

我想对(1)给出我的解释。

如果我的main()中有以下代码:

Base b {100}; // overloaded constructor
Base b1 {b}; // copy constructor
b = b1; // copy assignment

我认为发生的是a1调用了 no args 构造函数,这显然是因为没有 arguments 被传递到 object 的构造中。 初始化a2时,会生成a1的临时副本,然后针对Base class 评估运算符,因此运行Base重载复制分配块,并通过return *thisa1 object 返回到引用a2

为了解释我对第二个问题的想法,

当声明 function 或方法时,我认为所有参数都需要一个名称(我当然可能错了)。

如果我的重载复制分配块假设写为:

Base &lhs operator = (const Base &rhs)

我是否正确地说lhs指的是a2但是由于隐含的this参数,我们不对lhs做任何事情,我们不需要在运算符之前的 & 符号后面给出参数名称?

这个复制赋值运算符是如何工作的?

编辑:

Base& operator=(Base const& rhs) {
    cout << "Base operator=\n";
    value = rhs.value;
    return *this;
}

赋值运算符只是一个 function 调用。 在这个特定的类的情况下,编译器将合成一个做正确的事情,但如果你想要cout的副作用用于教育目的,你就做对了。

您也可以在 function 风格的方法中调用它:

b.operator=(b1);

b = b1; 只是上面的语法糖。

赋值运算符应该是自赋值安全的。 但一般指导是在不明确检查自分配情况的情况下使其安全,这是“不好的”,因为它针对病态情况进行了优化。

在您的实现中,没有自分配检查是安全的。

我更喜欢在Base const& order 中而不是const Base& order 中指定限定符,因为一般规则是“限定符总是绑定到它最左边的东西”,一般规则的例外是“......除非限定符出现首先,在这种情况下,它会绑定到它直接右边的那个东西上。” 当人们掌握了规则的例外而不是一般规则,然后在他们的脑海中解析Base*const*时遇到了麻烦,这就会成为一个问题。

operator 关键字之前的引用是否需要参数名称?

它的名字是*this 它是返回类型,而不是参数,因此它没有参数名称。

有些人对“为什么 C++ 使用this作为指向自身的指针,而不是作为对自身的引用”感到困扰。

从 C++ 的演变来看,这是一个历史异常。 最初,有一个this指针,还没有在语言中添加引用。

事后看来, this将是一个参考。 但是那艘船已经航行了。

在我自己的代码中,只是为了让它更清晰,我会这样做:

auto& self = *this;
self[i] = 5;

...而不是更令人困惑的(imo)...

(*this)[i] = 5;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM