конструктор копирования и STL
От: nick_chuck  
Дата: 21.10.09 12:27
Оценка:
Вот такая фигня:
1. пишу класс

class C2Point
{
public:
double x;
double y;
C2Point(C2Point& p):x(p.x),y(p.y){};
C2Point(){};
};

И функцию:

void FFF(void)
{
C2Point p;
std::vector<C2Point> ppp;
ppp.push_back(p);
}

Компилирую. Получаю
error C2558: class 'C2Point' : no copy constructor available or copy constructor is declared 'explicit'

Получается, в векторе я не имею права использовать явно написанные конструкторы копирования? Но этот конструктор копирования мне нужен, я этот класс уже лет 10 использую с этим конструктором, пока не попытался вставить его в вектор. Кто подскажет, можно обойти это ограничение?
Re: конструктор копирования и STL
От: Nik_1 Россия  
Дата: 21.10.09 12:35
Оценка: 1 (1) +2
C2Point(const C2Point& p):x(p.x),y(p.y){};
Re[2]: конструктор копирования и STL
От: nick_chuck  
Дата: 21.10.09 12:41
Оценка: :)
Здравствуйте, Nik_1, Вы писали:


N_>
N_>C2Point(const C2Point& p):x(p.x),y(p.y){};
N_>


Век живи... Спасибо
Re: конструктор копирования и STL
От: Кодт Россия  
Дата: 21.10.09 14:54
Оценка: +1
Здравствуйте, nick_chuck, Вы писали:

Не мучай животину.

Если у объекта конструктор копирования не определён руками (его сигнатура T::T(const T&) или T::T(T&), как сделал ты), то компилятор определит его сам (с сигнатурой T::T(const T&)). И логика там будет — почленное копирование.
То же самое относится к оператору копирующего присваивания.
Что важно, наличие других конструкторов и операторов присваивания не отменяет эти неявные определения. В отличие от дефолтного конструктора (T::T()) — который неявно определён, только если нет других конструкторов.

Только в случае, если почленное копирование тебя не устраивает, нужно определять конструктор копирования.

Вот с оператором присваивания ситуация хитрее. Там нет бесплатной (обеспеченной компилятором) транзакционности, при возникновении исключения можно получить недоприсвоенный объект.
Поэтому, даже если нужно почленное копирование, может пригодиться вот такой трюк
class T
{
    // члены-данные
    .....
    .....
    .....
public:
    void swap(T& other) throw()
    {
        if(this == &other) return;
        swap(x, other.x);
        swap(y, other.y);
        .....
    }
    friend void swap(T& left, T& right) throw() { return left.swap(right); }
    
    T& operator=(T& right)
    {
        if(this != &right) // если присваиваем сами себе, нет смысла трудиться
            T(right) // во время конструирования может вылететь исключение
                .swap(*this); // но в момент собственно присваивания - ничего уже не вылетит
                    // а старые ресурсы будут освобождены деструктором временного объекта
        return *this;
    }
};


Но в случае C2Point, где члены примитивные, исключению взяться неоткуда. Так что можно не волноваться и позволить компилятору сделать всё за тебя.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re: конструктор копирования и STL
От: Alexander G Украина  
Дата: 21.10.09 15:28
Оценка: :)
Здравствуйте, nick_chuck, Вы писали:

_> Но этот конструктор копирования мне нужен, я этот класс уже лет 10 использую с этим конструктором,


Да ну?
Русский военный корабль идёт ко дну!
Re: конструктор копирования и STL
От: igna Россия  
Дата: 22.10.09 04:53
Оценка: 1 (1)
Здравствуйте, nick_chuck, Вы писали:

_>error C2558: class 'C2Point' : no copy constructor available or copy constructor is declared 'explicit'


Нередко бывает полезно откомпилировать непонятные куски кода при помощи Comeau Online; в данном случае сообщение об ошибке, выдаваемое Comeau, по крайней мере не вводит в заблуждение в отличие от процитированного тобой сообщения Visual C++.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.