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

Posted

技术标签:

【中文标题】如何在类的成员函数中调用复制构造函数?【英文标题】:How do you call the copy constructor within a member function of a class? 【发布时间】:2009-12-04 04:37:10 【问题描述】:

这是我得到的:

void set::operator =(const set& source)

    if (&source == this)
        return;

    clear();

    set(source);

这是我得到的错误:

vset.cxx:33: 错误:'source' 的声明遮蔽了参数

我该如何正确地做到这一点?

【问题讨论】:

第 33 行是行:set(source); 【参考方案1】:

你正在寻找复制交换成语:

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

【讨论】:

copy-swap idiom 的优点是它分离了关注点:copy ctor 可能会抛出异常,这在这一点上是可以的,因为您没有更改 'this' 实例中的任何状态;复制完成后,将使用交换来交换“this”的状态与没有异常风险的副本。【参考方案2】:

我相信set(source); 您正在尝试调用复制 ctor。你不能在 C++ 中这样做,即你不能显式调用 ctor。你可以做的是写一个私人clone 方法并在复制 ctor 和赋值运算符中调用它。

【讨论】:

@Ring:我建议您阅读 C++ 中的对象生命周期。您不能在已经构造的东西上调用构造函数这一事实在很大程度上是构造一次,销毁一次的一部分,这保证了您在 C++ 中拥有所有对象(假设没有肮脏的技巧)。这是使 C++ 中的构造函数不仅仅是在许多其他语言中的构造后初始化函数的原因之一。绝对不跛脚(恕我直言)! Clone() 是 Java 处理事物的方式。这不是 C++ 的标准处理方式【参考方案3】:

正如您所指出的,set(source); 是问题的根源(不是双关语)。这并没有像你想象的那样做——它没有尝试调用复制 ctor。相反,它基本上等同于:set source;——即它试图定义一个名为set 的对象source——括号是多余的,但允许使用。

您可以在 ctor(或几乎任何您想要的地方)中调用复制 ctor,但无论如何它不会达到您想要的效果 - 复制 ctor 会创建一个副本,因此即使您确实调用了它,它也会只需创建一个临时对象,该对象会在该语句结束时消失。

如前所述,您可能想要的是一个私有函数,用于将数据从一个对象复制到另一个对象,然后从您的复制 ctor 和复制赋值运算符中使用它。更好的是,使用可以由默认复制 ctor 和复制赋值运算符正确处理的对象来定义它。

【讨论】:

【参考方案4】:

该错误通常是由于局部变量的名称与函数参数相同。您可以发布更多代码吗?

【讨论】:

【参考方案5】:

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

如果您想避免复制构造函数和 operator= 之间的代码重复,我建议使用一个私有函数来完成共同工作,并从复制构造函数和 operator= 中调用它。

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

*this = source;

但是,我认为这不是一个好主意,尤其是如果您有虚函数或 operator=() 函数假定一个完全构造的对象(它可能会这样做)。

【讨论】:

【参考方案6】:

我不知道你的头文件指定的细节,但我会尝试这样的事情(你可能需要为你的特定应用程序修改它):


void set::operator =(const set& source)

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])));
    


-乔尔

【讨论】:

以上是关于如何在类的成员函数中调用复制构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

c++,类的对象作为形参时一定会调用复制构造函数吗?

复制构造函数中的c ++用户定义成员

第四章总结

如何获得指向类的复制构造函数的成员函数指针?

如何在类构造函数中等待异步操作? [复制]

c++ 类的复制函数