C++ 赋值奇怪的行为

标签 c++ variable-assignment copy-constructor

您能解释一下以下代码的输出吗?变量在赋值结束时更改其值。

#include <iostream>
#include <new>

using namespace std;

template<class CRTP>
class object_t {
public:
    object_t<CRTP> &operator=(const object_t<CRTP> &a) {
        ((CRTP*)this)->~CRTP();
        new ((CRTP*)this) CRTP(*(const CRTP*)&a);
        cout << "Value in assignment: " << ((CRTP*)this)->n << endl;
        return *this;
    }
};

class darr_t : public object_t<darr_t> {
public:

    int n;

    darr_t(const darr_t &a) : n(a.n + 1) {
       cout << "Value in constructor: " << n << endl;  
    }

    darr_t(int pn) : n(pn) {}
};

int main() {

    darr_t tmp(42);
    darr_t tmp2(55);
    tmp = tmp2;

    cout << "Value in main: " << tmp.n << endl;

    return 0;
}

输出:

Value in constructor: 56
Value in assignment: 56
Value in main: 55

预期输出:

Value in constructor: 56
Value in assignment: 56
Value in main: 56

编辑: 感谢@Cheersandhth.-Alf 和@Mr_Hic-up 的回答! 问题是默认的 darr_t::operator= 首先调用基类型的赋值,但之后它为 darr_t 对象的成员调用赋值(覆盖)!

最佳答案

您观察该行为是因为:

  1. 编译器为 darr_t 定义了隐式复制赋值运算符。
  2. 隐式复制赋值首先调用基类的复制赋值运算符,然后再执行成员变量的复制赋值。

以下是来自 http://en.cppreference.com/w/cpp/language/as_operator 的相关文档:

Implicitly-declared copy assignment operator

If no user-defined copy assignment operators are provided for a class type (struct, class, or union), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T& T::operator=(const T&) if all of the following is true:

each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B&

each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M&

Otherwise the implicitly-declared copy assignment operator is declared as T& T::operator=(T&). (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument)

关于C++ 赋值奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24330804/

相关文章:

c++ - Qt 本地安全网络套接字

c++ - 如何继承纯虚函数C++的实现

c++ - 为什么 main() 参数 argv 的类型是 char*[] 而不是 const char*[]?

c++ - 按值传递对象时出现断言错误——这是我的复制构造函数?

c++ - 继承和复制构造函数——如何从基类初始化私有(private)字段?

c++ - 如何使父类的方法使用不同的变量?

java - 覆盖这个变量的正确方法是什么?

c++ - 通过引用分配 vector

Java:for循环中的对象数组赋值

c++ - 使用shared_ptr时需要实现析构函数、拷贝构造函数、赋值运算符