含const成员的类为何可拷贝/移动?解惑Abseil Tips 177表述
带const成员的类:构造与赋值的关键区别
具体来说,若类包含const成员,则无法对其进行赋值(无论是拷贝赋值还是移动赋值)。C++语言对此的处理是:若类型存在const成员,编译器不会合成拷贝赋值和移动赋值运算符。
我编写了一段C++代码,发现类对象可以被拷贝和移动,请问应如何理解这段表述?
代码如下:
#include <iostream> class Stitch { public: Stitch(int in):num(in) { std::cout << "c'tor, address:" << this << std::endl; } ~Stitch() { std::cout << "d'tor, address:" << this << std::endl; } const int num; const std::size_t kAddr = (int)(this); }; int main() { Stitch s1(1); std::cout << "s1 address: " << &s1 << " " << s1.num << std::endl; Stitch s2 = s1; std::cout << "s2 address: " << &s2 << " " << s2.num << std::endl; Stitch s3 = std::move(s1); std::cout << "s3 address: " << &s3 << " " << s3.num << std::endl; Stitch s4 = Stitch(4); std::cout << "s4 address: " << &s4 << " " << s4.num << std::endl; }
你混淆了对象构造和对象赋值的概念,这是理解这段表述的核心:
你的代码里的操作都是构造新对象:
Stitch s2 = s1;是调用拷贝构造函数,用已存在的s1初始化新对象s2,不属于赋值操作。Stitch s3 = std::move(s1);本质也是构造(因你自定义了析构函数,C++会抑制移动构造的合成,实际调用的是拷贝构造),同样不是赋值。Stitch s4 = Stitch(4);是用临时对象初始化s4,属于拷贝/移动构造范畴(C++17后会优化为直接构造)。
那段表述针对的是赋值操作:
当你尝试对已存在的对象进行赋值时,比如写s2 = s1;或s2 = std::move(s1);,编译器会报错——因为类包含const成员,编译器不会自动合成拷贝赋值运算符和移动赋值运算符,而你也没有手动定义这些运算符。
const成员的特性是初始化后无法修改,赋值操作本质是要修改对象的成员(包括const成员),这违反了const的语义,所以编译器不会合成这类运算符;但构造是初始化新对象,const成员可以在初始化阶段设置值,因此不受影响。
内容的提问来源于stack exchange,提问作者Biear
相关产品推荐
相关产品推荐

