Как вы вызываете конструктор копирования внутри функции-члена класса? - PullRequest
0 голосов
/ 04 декабря 2009

Вот что у меня есть:

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

    clear();

    set(source);
}

И вот ошибка, которую я получаю:

vset.cxx: 33: ошибка: объявление 'source' затеняет параметр

Как мне правильно это сделать?

Ответы [ 6 ]

10 голосов
/ 04 декабря 2009

Вы ищете код замены свопа:

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 голосов
/ 04 декабря 2009

Я думаю, что с set(source); вы пытаетесь вызвать копирование ctor. Вы не можете сделать это в C ++, то есть вы не можете явно вызывать ctor. Что вы можете сделать, это написать личное clone и вызовите его как в ctor, так и в операторе присваивания.

1 голос
/ 04 декабря 2009

Как вы заметили, set(source); является источником (не каламбур) проблемы. Это не совсем то, что вы думаете - это не попытка вызвать копию ctor. Вместо этого он в основном эквивалентен: set source; - то есть он пытается определить set объект с именем source - круглые скобки избыточны, но разрешены.

Вы можете вызвать копию ctor в ctor (или где угодно), но в любом случае это не приведет к тому, что вы хотите - копия ctor создает копию, поэтому, даже если вы ее вызывали, она бы просто создайте временный объект, который испарится в конце этого оператора.

Как уже упоминалось, вам, вероятно, нужна частная функция для копирования данных из одного объекта в другой, а затем использовать их как из своего ctor-копии, так и из вашего оператора назначения копирования. Более того, определите его, используя объекты, которые могут обрабатываться корректно с помощью ctor по умолчанию и операторов назначения копирования.

0 голосов
/ 11 декабря 2009

Я не знаю деталей того, что указывает ваш заголовочный файл, но я бы попробовал что-то вроде этого (возможно, вам придется изменить его для вашего конкретного приложения):


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

0 голосов
/ 04 декабря 2009

Сообщение об ошибке, которое вы видите, не соответствует вопросу, но я не знаю, насколько оно актуально. Ответ на ваш вопрос заключается в том, что вы не можете вызвать конструктор копирования из своего кода, потому что объект уже создан.

Если вы хотите избежать дублирования кода между конструктором копирования и оператором =, я предлагаю использовать частную функцию, выполняющую общую работу, и вызывать ее как из конструктора копирования, так и оператора =.

Для справки, вы можете вызвать operator = из конструктора копирования, выполнив:

*this = source;

Однако я не думаю, что это хорошая идея, особенно если у вас есть виртуальные функции или если функция operator = () предполагает полностью сконструированный объект (что, вероятно, имеет).

0 голосов
/ 04 декабря 2009

Эта ошибка обычно является результатом того, что локальная переменная названа так же, как аргумент функции. Можете ли вы опубликовать больше своего кода?

...