2009-12-04 2 views
0

Вот что я получил:Как вы называете конструктор копирования внутри функции-члена класса?

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

    clear(); 

    set(source); 
} 

А вот ошибка я получаю:

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

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

+0

линия 33 является линией: набор (источник); – Ring

ответ

3

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

+0

Черт, вот и ламе. Благодаря! – Ring

+3

@Ring: Я бы рекомендовал вам прочитать о жизни объектов в C++. Тот факт, что вы не можете вызвать конструктор над чем-то, что уже построено, - это очень большая часть построенного однажды, уничтоженного после того, как вы гарантируете, что у вас есть на C++ для всех объектов (при отсутствии грязных трюков). Это одна из вещей, которая делает конструкторы на C++ больше, чем просто функции инициализации после построения, которые они находятся на многих других языках. Определенно не хромой (ИМХО)! –

+0

Clone() - это способ работы с Java. Это не стандартный способ делать вещи в C++. –

0

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

0

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

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

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

*this = source; 

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

1

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

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

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

10

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

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 
} 
+1

. Преимущество идиомы копирования-замены сводится к тому, что она отделяет проблемы: copy ctor может генерировать исключение, и это нормально, потому что вы не изменили какое-либо состояние в «этом» экземпляре; После копирования создается своп, который обменивает состояние «это» с копией без риска исключения. –

0

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


недействительными устанавливается :: оператор = (Const установить & источник)
{

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

Похож на хорошую стратегию. –

Смежные вопросы