Guía de desarrollo de Boost - 4.1 no copiable

no copiable

noncopyable permite que los programas implementen fácilmente una clase que prohíbe la copia.

noncopyable se encuentra en el espacio de nombres boost. Para usar componentes no copiables, debe incluir el archivo de encabezado <boost/noncopyable.hpp> o <boost/utility.hpp> (este último contiene la implementación de varias herramientas pequeñas):

#include <boost/noncopyable.hpp> //或者
#include <boost/utility.hpp> 

principio

Al definir una clase en C++, si el constructor de copia y el operador de asignación de copia no están definidos explícitamente, el compilador generará automáticamente estas dos funciones para nosotros.

Por ejemplo:

class empty_class();

Para una clase R "vacía" tan simple, el compilador agregará "silenciosamente" un constructor de copia y un operador de asignación de copia cuando lo procese. El código real es similar a:

class empty_class
{
    
    
public: //构造和析构暂时忽略
   empty_class (const empty_class &){
    
    ...} //拷贝构造函数
   empty_class & operator=(const empty_class &){
    
    ...} //拷贝赋值
};

En general, esto es útil, por ejemplo, puede admitir automáticamente swap(), ajustarse a la semántica de copia del contenedor y puede colocarse en un contenedor estándar para su procesamiento, pero a veces no necesitamos la semántica de copia del contenedor. class y esperamos prohibir la copia de la instancia de la clase.

Este es un modismo c++ muy clásico. El principio es fácil de entender. Solo necesita privatizar el constructor de copias y el operador de asignación de copias, y el código escrito a mano también es muy simple (scoped_ptr usa este modismo), por ejemplo:

class do_not_copy
{
    
    
private:
   do_not_copy (const do_not_copy &); //私有化,声明即可,不需要实现代码
   void operator=(const do_not_copy &); //私有化,声明即可,不需要实现代码
};

Pero si hay una gran cantidad de clases de este tipo en el programa, es bastante tedioso escribir dichos códigos repetidamente, y cuantos más códigos aparezcan, más fácil será aumentar la posibilidad de errores de escritura a mano. Si bien también es posible usar macros con parámetros para reducir la duplicación, la solución es menos elegante.

uso

noncopyable proporciona una solución simple y clara para implementar clases no copiables: simplemente derive de boost::noncopyable.

Usando noncopyable, el ejemplo anterior se puede simplificar a:

#include <boost/noncopyable.hpp>
class do_not_copy: boost::noncopyable
{
    
    ...};

Tenga en cuenta que aquí se permite el uso de la herencia privada predeterminada. También podemos escribir explícitamente modificadores privados o públicos, pero el efecto es el mismo. Por lo tanto, escribir directamente de esta manera ahorra algo de entrada de código, es más claro y muestra la relación HAS-A (en lugar de ISA).

Si alguien más escribe el código por error (probablemente sin leer detenidamente el documento de la interfaz), intentando copiar la construcción o asignar do_not_copy, fallará la revisión del compilador:

do_not_copy d1; //一个不可拷贝对象
do_not_copy d2(d1); //企图拷贝构造,编译出错
do_not_copy d3; //另一个不可拷贝对象
d3 = d1; //企图拷贝赋值,编译出错

La compilación con GCC generará un mensaje de error similar al siguiente:

note: 'do_not_copy::do_not_copy(const do_not_copy&)'
is implicitly deleted because the default definition would be ill-formed:
class do_not_copy: boost::noncopyable
error: use of deleted function 'boost::noncopyable_ ...'

Este mensaje de error nos dice claramente: la clase usa boost::noncopyable para deshabilitar (eliminar) la construcción de la copia, y no se puede llamar al constructor de la copia.

Siempre que sea posible, use boost::noncopyable, expresa la intención del diseñador de la clase sin ambigüedades, es más fácil de usar y funciona bien con otras bibliotecas de Boost.

lograr

class noncopyable
{
    
    
protected:
   noncopyable() {
    
    }
   ~noncopyable() {
    
    }
private:
   noncopyable (const noncopyable&); //私有化拷贝构造和拷贝赋值
   const noncopyable& operator=(const noncopyable&);
};

Por lo tanto, cuando nuestra clase personalizada es una subclase de no copiable, privatizará automáticamente el constructor de copia no copiable de la clase principal, lo que prohibirá a los usuarios acceder al constructor de copia y a la función de asignación de copia desde el exterior.

Si usa las nuevas palabras clave predeterminadas y eliminadas del estándar C++ 11, no copiable se puede implementar más claramente de la siguiente manera:

class noncopyable
{
    
    
protected:
    noncopyable() = default; //默认的构造和析构是保护的
    ~noncopyable() = default; //使用默认实现
    //使用delete关键字禁用拷贝构造和拷贝赋值
    noncopyable(const noncopyable&) = delete;
    const noncopyable& operator=(const noncopyable&) = delete;
};

ejemplo de código

#include <iostream>
using namespace std;

#include <boost/noncopyable.hpp>

//
class do_not_copy : boost::noncopyable
{
    
    };

//


int main()
{
    
    
	do_not_copy d1;
	//do_not_copy d2(d1);
	//do_not_copy d3;
	//d3 = d1;
}

Supongo que te gusta

Origin blog.csdn.net/qq_36314864/article/details/132097951
Recomendado
Clasificación