阅读源码时,发现一个小知识点,关于boost::noncopyable类的,查看该类源码发现,其拷贝构造函数和拷贝复制运算符被禁用了,这样子类在继承时,子类的拷贝构造函数和拷贝复制运算符也会被禁用。
boost::noncopyable类源码如下:
class noncopyable
{
protected:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
BOOST_CONSTEXPR noncopyable() = default;
~noncopyable() = default;
#else
noncopyable() {}
~noncopyable() {}
#endif
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
noncopyable( const noncopyable& ) = delete;
noncopyable& operator=( const noncopyable& ) = delete; //被禁用
#else
private: // emphasize the following members are private //被禁用
noncopyable( const noncopyable& );
noncopyable& operator=( const noncopyable& );
#endif
};
为了验证这一点,写了一个demo,源码如下:
#include <iostream>
class Basic
{
public:
Basic() = default;
~Basic() = default;
protected:
Basic(const Basic& ) = delete;
Basic& operator=(const Basic& ) = delete;
};
class Derived : public Basic
{
public:
Derived() = default;
Derived(int m) : value(m) {}
private:
int value;
};
int main() {
Derived d1;
Derived d2(2);
Derived d3(d1); //该语句clion编译时会报错
return 0;
}
结论1:
派生类继承基类时,若派生类没有定义自己的拷贝构造函数和拷贝复制运算符,则基类的拷贝属性会传递到派生类。
那么问题来了,如果派生类有自己的拷贝构造函数和拷贝复制运算符呢?接着看下一段代码,源码如下:
#include <iostream>
class Basic
{
public:
Basic() = default;
~Basic() = default;
protected:
Basic(const Basic& ) = delete;
Basic& operator=(const Basic& ) = delete;
};
class Derived : public Basic
{
public:
Derived() = default;
Derived(int m) : value(m) {}
Derived(const Derived& derived) : value(derived.value) {} //派生类的拷贝构造函数
Derived& operator=(const Derived& derived) //派生类的拷贝复制运算符
{
value = derived.value;
}
public:
int value;
};
int main() {
Derived d1;
Derived d2(2);
Derived d3(d2); //该语句顺利执行
std::cout << d3.value << std::endl;
return 0;
}
结论2
派生类继承基类时,若派生类已定义自己的拷贝构造函数和拷贝复制运算符,则基类的拷贝属性不会传递到派生类。
问题
在定义拷贝构造函数的同时,为何通常会定义拷贝复制运算符?