由于删除了基类复制构造函数,派生类无法知道如何复制基类对象。这将禁用编译器提供的任何隐式复制构造函数。
来自 cppreference:
类 T 的隐式声明或默认的复制构造函数是
如果满足以下任一条件,则定义为已删除:
当用户从删除默认复制构造函数但提供其默认实现来覆盖它的类继承时,继承 Q_DISABLE_COPY
会很有用。
struct Base {
Base() = default;
private:
Base(const Base &) = delete;
Base &operator=(const Base &) = delete;
};
struct Derived : Base {
Derived() = default;
Derived(const Derived&) : Derived() {}
Derived &operator=(const Derived&) {
return *this;
}
};
struct MoreDerived : Derived {};
int main() {
Derived d1;
Derived d2(d1); // Works fine!
Derived d3;
d3 = d1; // Works fine!
MoreDerived md1;
MoreDerived md2(md1); // Works fine!
MoreDerived md3;
md3 = md1; // Works fine!!
}
编辑:正如@SR_ 正确指出的那样,在 Derived
的上述实现中,Base
没有被复制构造。我只是想说明一个事实,当继承层次结构中的另一个类被修改时,很容易引入一个无意的复制构造函数。
,
在提交 a2b38f6
之前,QT_DISABLE_COPY
被定义为 like this(感谢 Swift - Friday Pie 在评论中指出这一点):
#define Q_DISABLE_COPY(Class) \
Class(const Class &) Q_DECL_EQ_DELETE;\
Class &operator=(const Class &) Q_DECL_EQ_DELETE;
还有Q_DECL_EQ_DELETE
like this:
#ifdef Q_COMPILER_DELETE_MEMBERS
# define Q_DECL_EQ_DELETE = delete
#else
# define Q_DECL_EQ_DELETE
#endif
Q_COMPILER_DELETE_MEMBERS
在 C++11 支持(或至少是它的足够新的草案以支持 = delete
)可用时得到定义。
因此,如果您当时使用 C++03 编译器编译 Qt,它会编译如下:
struct Base {
Base() {};
private:
Base(const Base &);
Base &operator=(const Base &);
};
struct Derived : Base {};
int main() {
Derived d1;
Derived d2(d1);
Derived d3;
d3 = d1;
}
使用 g++ -std=c++03
编译它会产生以下错误:
<source>: In copy constructor 'Derived::Derived(const Derived&)':
<source>:9:8: error: 'Base::Base(const Base&)' is private within this context
9 | struct Derived : Base {};
| ^~~~~~~
<source>:5:5: note: declared private here
5 | Base(const Base &);
| ^~~~
<source>: In function 'int main()':
<source>:13:18: note: synthesized method 'Derived::Derived(const Derived&)' first required here
13 | Derived d2(d1);
| ^
<source>: In member function 'Derived& Derived::operator=(const Derived&)':
<source>:9:8: error: 'Base& Base::operator=(const Base&)' is private within this context
9 | struct Derived : Base {};
| ^~~~~~~
<source>:6:11: note: declared private here
6 | Base &operator=(const Base &);
| ^~~~~~~~
<source>: In function 'int main()':
<source>:15:10: note: synthesized method 'Derived& Derived::operator=(const Derived&)' first required here
15 | d3 = d1;
| ^~
当时,“你的编译器会为你精心创建它”在技术上是正确的,但实际上并非如此,因为创建它的编译器会导致编译失败,只是出现一个不同的(可以说是不太清楚的)错误。我现在确信,既然 = delete
被无条件地使用,这已经完全不正确了,所以我计划要求 Qt 的维护者删除/改写他们文档的那部分。
本文链接:https://www.f2er.com/215994.html