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

问题描述 投票:0回答:7

这是我得到的:

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

    clear();

    set(source);
}

这是我得到的错误:

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

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

c++ class constructor copy
7个回答
11
投票

您正在寻找复制交换习语:

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
}

3
投票

我相信

set(source);
你正试图打电话给复制者。您不能在 C++ 中执行此操作,即您不能显式调用该构造函数。你能做的就是写一个私人的
clone
方法并在复制构造函数和赋值运算符中调用它。


1
投票

正如您所指出的,

set(source);
是问题的根源(没有双关语)。这并没有按照你想象的那样做——它并没有试图调用复制者。相反,它基本上相当于:
set source;
- 即它试图定义一个名为
set
source
对象 - 括号是多余的,但是允许的。

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

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


0
投票

该错误通常是由于局部变量与函数参数的名称相同而导致的。你能发布更多你的代码吗?


0
投票

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

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

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

*this = source;

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


0
投票

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


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

}


-乔尔


0
投票

我发现,如果您使用特定的运算符组合,则可以像您预期的那样使用复制构造函数:

this->
,然后使用范围解析运算符调用复制构造函数,与函数标题中出现的方式相同宣言。 (假设您定义了自己的复制构造函数。)该语句看起来像
this->ClassName::ClassName(givenObject);
并且我在下面包含了一个上下文模板。 请注意,您还可以以相同的方式调用析构函数(带有波浪号),但您不需要
this->
。 我在 Visual Studio 中对下面的代码运行了调试器,它似乎按预期工作,但如果您对不同版本的 C++ 有问题,请告诉我们!

void ClassName::operator=(const ClassName& givenObject)
{
    if (this == &givenObject)
        return;

    ClassName::~ClassName();
    this->ClassName::ClassName(givenObject);
}

ClassName::~ClassName()
{
    delete[] myArray;
}
ClassName::ClassName(const ClassName& existingObject)
{
 // Your customized copy constructor code goes here.
© www.soinside.com 2019 - 2024. All rights reserved.