在 QT 中,自定义类放入QList
时,编译时报错 'PanelItem::PanelItem(const PanelItem &)': attempting to reference a deleted function
分析解决
在调用QList::append(const T &value)
增加元素的时候,内部存在对添加值的复制,调用了复制构造函数。这就是编译时出错,静态检查不出错的原因。
PanelItem
是自定义类,继承了 QGraphicsItem
,乍一看编译器应该自动生成复制构造函数才对,但是 QGraphicsItem
继承了 QGraphicsObject
而 QGraphicsObject
继承了QObject
,QObject
弃置了复制构造函数,所以我们的自定义的拷贝构造函数也被弃置了
知道了原因,解决也很简单。自定义复制构造函数,或者干脆在QList
存指针
复制构造函数
显式复制构造函数
自定义复制构造函数时,需要遵守,类 T 的复制构造函数是非模板构造函数,其首个形参为 T&
、const T&
、volatile T&
或 const volatile T&
,而且要么没有其他形参,要么剩余形参均有默认值
通过以下代码,规定编译器行为
class_name ( const class_name & ) = default;
强制编译器生成默认的构造函数class_name ( const class_name & ) = delete;
强制编译器阻止隐式复制构造函数
隐式复制构造函数
若没有显式的定义复制构造函数,编译器会附加隐式声明的复制构造函数 当以下各项均为真时,这个隐式声明的复制构造函数拥有形式 T::T(const T&)
T
的每个直接与虚基类 B 均拥有复制构造函数,其形参为const B& 或 const volatile B&
T
的每个类类型或类类型数组的非静态数据成员 M 均拥有复制构造函数,其形参为const M&
或const volatile M&
否则,隐式声明的复制构造函数是T::T(T&)
丢弃的隐式复制构造函数
若下列任何条件为真,编译器会附加 class_name ( const class_name & ) = delete;
(c++11)
T
拥有无法复制的非静态数据成员(拥有被弃置、不可访问或有歧义的复制构造函数)T
拥有无法复制的父类或虚基类(拥有被弃置、不可访问或有歧义的复制构造函数)T
拥有带被弃置或不可访问的析构函数的父类或虚基类T
是联合式的类,且拥有带非平凡复制构造函数的变体成员T
拥有右值引用类型的数据成员T
拥有用户定义的移动构造函数或移动赋值运算符(此条件只导致隐式声明的,而非预置的复制构造函数被弃置)
平凡复制构造函数
当下列各项全部为真时,类 T 的复制构造函数为平凡的:
- 它不是用户提供的(即它是隐式定义或预置的),且若它被预置,则其签名与隐式定义的相同
T
没有虚成员函数;T
没有虚基类;- 为
T
的每个直接基类选择的复制构造函数都是平凡的; - 为
T
的每个类类型(或类类型数组)的非静态成员选择的复制构造函数都是平凡的;
调用情形
当类的对象需要拷贝时,复制构造函数将会被调用。以下情况都会调用复制构造函数:
- 一个对象以值传递的方式传入函数体
- 一个对象以值传递的方式从函数返回
- 一个对象需要通过另外一个对象进行初始化
文档信息
- 本文作者:wzx
- 本文链接:https://masterwangzx.com/2019/08/30/copy-construction/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)