复制构造函数可以采用非const参数吗?

Alc*_*ott 5 c++

我有这个问题,有foo()如下功能,

vector<ClassA> vec;

void foo()
{
    ClassA a;   //inside foo, a ClassA object will be created
    a._ptr = new char[10];

    vec.push_back(a);   //and this newly created ClassA object should be put into vec for later use
}
Run Code Online (Sandbox Code Playgroud)

而AFAIK vec将调用ClassAcopy-ctor来制作新创建的对象的副本a,这就是问题所在.如果我ClassA按照通常的方式定义副本,

ClassA::ClassA(const ClassA &ra) : _ptr(0)
{
    _ptr = ra._ptr;
}
Run Code Online (Sandbox Code Playgroud)

然后对象a及其副本(由vec创建)将_ptr指向同一区域的指针,当foo完成时,a将调用析构函数释放_ptr,然后a复制vec将是一个悬空指针,对吧?由于这个问题,我想以ClassA这种方式实现copy-ctor,

ClassA::ClassA(ClassA &ra) : _ptr(0) //take non-const reference as parameter
{
    std::swap(_ptr, a._ptr);
}
Run Code Online (Sandbox Code Playgroud)

我的实施是否正常?或者任何其他方式可以帮助完成这项工作?

Ker*_* SB 7

回答你的名义问题:是的,T具有一个类型的强制参数的类的任何构造函数T &T const &(它可能还有其他默认参数)是一个复制构造函数.在C++ 11中,还有一个移动构造函数,它需要一个类型的参数T &&.

拥有一个实际改变参数的非常量复制构造函数会给你的类带来非常不寻常的语义(通常是"传递语义")并且应该被广泛记录; 它还可以防止你复制一些不变的东西(显然).旧std::auto_ptr<T>的确如此.

如果可能的话,新的C++ 11样式的可变rvalue引用和移动构造函数为原始对象中不再需要的"移动"资源的问题提供了更好的解决方案.这是因为右值引用是对可变对象的引用,但它只能绑定到"安全"表达式,例如临时或明确转换(通过std::move)并因此标记为一次性的事物.


yur*_*hek 4

C++11 为此引入了移动构造函数:

ClassA::ClassA(ClassA&& ra)
: _ptr(ra._ptr)
{
    ra._ptr = nullptr;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以声明_ptr为共享指针:

std::shared_ptr<char[]> _ptr;
Run Code Online (Sandbox Code Playgroud)

然后默认的派生复制构造函数就可以了。

  • 可悲的是,我没有使用 C++11 (2认同)