简体   繁体   中英

How do you call the copy constructor within a member function of a class?

Here's what I've got:

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

    clear();

    set(source);
}

And here's the error I get:

vset.cxx:33: error: declaration of 'source' shadows a parameter

How do I properly do this?

You are looking for the copy swap idiom:

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
}

I believe with set(source); you are trying to call copy ctor. You can not do that in C++ ie you can not explicitly invoke the ctor. What you can do is write a private clone method and call it in both copy ctor and assignment operator.

As you've noted, set(source); is the source (no pun intended) of the problem. This isn't doing quite what you think it is -- it's not attempting to invoke a copy ctor. Instead, it's basically equivalent to: set source; -- ie it's attempting to define a set object named source -- the parentheses are redundant but allowed.

You can invoke a copy ctor in a ctor (or just about anywhere you want to) but it's not going to to what you want anyway -- a copy ctor creates a copy, so even if you did invoke it, it would just create a temporary object, which would evaporate at the end of that statement.

As already mentioned, what you probably want is a private function to copy the data from one object to another, then use that from both your copy ctor and your copy assignment operator. Better still, define it using objects that can be handled correctly by the default copy ctor and copy assignment operators.

That error is usually the result of having a local variable named the same as a function argument. Can you post more of your code?

The error message you are seeing doesn't match the question, but I don't know that it is relevant. The answer to your question is that you cannot call the copy constructor from inside your code because the object is already constructed.

If you want to avoid code duplication between the copy constructor and operator=, I suggest having a private function that does the common work, and call that from both the copy constructor and operator=.

For reference, you could call operator= from copy constructor by doing:

*this = source;

However, I don't think that is a good idea especially if you have virtual functions or if the operator=() function assumes a fully constructed object (which it probably does).

I don't know the details of what your header file specifies, but I would try something like this (you may need to modify it for your specific application):


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

}


-Joel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM