2014-07-11 71 views
8

我发现自己正在做的一件常见事情是制作“几乎默认”的复制构造函数和赋值运算符。也就是说,我发现自己在编译器提供的复制和赋值操作符适用于大多数数据成员的情况下,但是有一个特定的数据成员需要以不同的方式处理。这意味着我必须显式创建一个拷贝构造函数/赋值运算符,包括明确列出所有具有简单复制语义的数据成员。这对于有相当数量的数据成员的类,或稍后在添加成员变量但未添加到复制构造函数/赋值运算符时会变得烦人。C++中的“几乎默认”复制构造函数(&赋值运算符)

有什么方法可以告诉C++编译器:显式声明的拷贝构造函数/赋值运算符应该像隐式运算一样运行,除了一些额外的代码之后运行吗? (并且是C++ 98兼容的语法,还是需要C++ 11或C++ 14支持?)

+16

为该数据成员实现适当的RAII包装,然后默认的构造函数将适用于所有内容。 –

回答

8

如果您可以按照Igor Tandetnik的建议,在适当的RAII包装中分离特定的处理:go为了那个原因。

如果您仍然需要在复制构造函数和/或赋值运算符中进行特定处理(例如将对象创建/赋值注册到容器或日志中),则可以将可以构建/分配的默认拷贝的数据成员分组一个单独的类,你作为一个基类或数据成员使用,您处理,因为复合材料,即:

struct x_base { 
    int a,b,c,d; 
    std::string name; 
}; 

struct x : x_base { 
    x(const x& other) 
     : x_base(other) 
    { 
     descr = "copied "; 
     descr += name; 
     descr += " at "; 
     descr += CurrentTimeAsString(); 
     std::cout << descr << "\n"; 
    } 
    void operator = (const x& other) 
    { 
     x_base::operator =(other); 
     descr = "assigned "; 
     descr += name; 
     descr += " at "; 
     descr += CurrentTimeAsString(); 
     std::cout << descr << "\n"; 
    } 
    std::string descr; 
}; 

当您以后添加数据成员不需要特定的处理,你可以简单地将它们添加到x_base 。

+1

这利用了这样一个原则,即非工会类的隐式定义拷贝构造函数执行其基础和成员的成员副本 (Standard C++,sect 12.8 pt 15)。但请注意,这对成员复制完成的顺序有一些限制。 – Christophe

相关问题