C++ 如何在类的成员函数中调用复制构造函数?

C++ 如何在类的成员函数中调用复制构造函数?,c++,class,constructor,copy,C++,Class,Constructor,Copy,以下是我得到的: void set::operator =(const set& source) { if (&source == this) return; clear(); set(source); } 下面是我得到的错误: vset.cxx:33:错误:“源”声明隐藏了一个参数 如何正确地执行此操作?该错误通常是由于将局部变量命名为与函数参数相同的结果。你能发布更多的代码吗 我相信有了setsource;您正在尝试调用复制cto

以下是我得到的:

void set::operator =(const set& source)
{
    if (&source == this)
        return;

    clear();

    set(source);
}
下面是我得到的错误:

vset.cxx:33:错误:“源”声明隐藏了一个参数


如何正确地执行此操作?

该错误通常是由于将局部变量命名为与函数参数相同的结果。你能发布更多的代码吗

我相信有了setsource;您正在尝试调用复制ctor。你不能在C++中这样做,也就是说,你不能显式地调用CtoR。你能做的就是编写一个私有克隆
方法,并在复制运算符和赋值运算符中调用它。

您看到的错误消息与问题不匹配,但我不知道它是否相关。您的问题的答案是,您不能从代码内部调用复制构造函数,因为对象已经被构造

如果您希望避免复制构造函数和运算符=(operator=)之间的代码重复,我建议使用一个执行公共工作的私有函数,并从复制构造函数和运算符=(operator=)调用该函数

作为参考,您可以通过执行以下操作从复制构造函数调用operator=:

*this = source;
但是,我认为这不是一个好主意,尤其是如果您有虚拟函数,或者operator=function假设一个完全构造的对象,它可能会这样做;问题的根源不是双关语。这并不像你想象的那样——它并没有试图调用一个拷贝。相反,它基本上等同于:set source;-i、 它试图定义一个名为source的set对象-括号是多余的,但是允许的

你可以在一个ctor中调用复制ctor,也可以在你想调用的任何地方调用复制ctor,但它无论如何都不会达到你想要的效果——复制ctor创建一个副本,所以即使你调用了它,它也只会创建一个临时对象,它会在语句末尾蒸发掉


如前所述,您可能需要的是一个私有函数,用于将数据从一个对象复制到另一个对象,然后从复制构造函数和复制赋值操作符使用该函数。更好的方法是,使用默认的“复制”操作符和“复制指定”操作符可以正确处理的对象来定义它

您正在寻找复制交换习惯用法:

set& set::operator=(set const& source)
{
    /* You actually don't need this. But if creating a copy is expensive then feel free */
    if (&source == this)
        return *this;

    /*
     * This line is invoking the copy constructor.
     * You are copying 'source' into a temporary object not the current one.
     * But the use of the swap() immediately after the copy makes it logically
     * equivalent.
     */
    set tmp(source);
    this->swap(tmp);

    return *this;
}

void swap(set& dst) throw ()
{
    // swap member of this with members of dst
}

我不知道头文件指定内容的详细信息,但我会尝试类似的方法,您可能需要为特定应用程序修改它:

无效集::运算符=常量集和源 {

}


-Joel

第33行是一行:setsource@环:我建议您在C++中阅读对象生命周期。事实上,你不能调用已经构建的东西的构造函数,这是构造的一次破坏的一次保证,它保证你在C++中对没有脏技巧的所有对象都有。这是使C++中的构造函数不仅仅是构造后初始化函数的一个原因,它们是许多其他语言的。绝对不是瘸子!克隆是Java处理事物的方式。在C++中,这不是标准的操作方式,复制交换习惯用法的优点是它可以分离关注点:复制ctor可能会抛出异常,这在此时是正常的,因为您没有更改“this”实例中的任何状态;复制完成后,使用交换,将“此”的状态与不存在异常风险的副本交换。
if (this == &source)
  {
     return;
  }

size_t i;
this->clear();
data=source.data;
for (i=0; i<source.child.size(); i++)
  {
     child.push_back(new set(*(source.child[i])));
  }