2015-08-26 2 views
1

Я хотел бы определить копию-конструктор, который просто присваивает объект к другому:Назначить весь объект в конструкторе копирования?

Заголовок:

#ifndef TESTCLASS_HPP 
#define TESTCLASS_HPP 

#include <boost/math/distributions/geometric.hpp> 

class Testclass { 
public: 
    Testclass(); 

    virtual ~Testclass(); 
private: 
    Testclass(const Testclass& orig); 
    int alpha; 
    boost::math::geometric_distribution <> geometricboost; 

}; 

#endif /* TESTCLASS_HPP */ 

Реализация:

#include "Testclass.hpp" 

Testclass::Testclass() : geometricboost(0) { 
} 

Testclass::Testclass(const Testclass& obj_ref) { 
    *this = obj_ref; 
} 

Testclass::~Testclass() { 
} 

Сам класс не содержит каких-либо указатели, но в конечном итоге объект. Возможно ли это сделать?

Если нет, то какой самый простой способ просто назначить?

Это дает ошибку:

Testclass.cpp: In copy constructor ‘Testclass::Testclass(const Testclass&)’: Testclass.cpp:13:46: error: no matching function for call to ‘boost::math::geometric_distribution::geometric_distribution()’ Testclass::Testclass(const Testclass& obj_ref) {

+2

Если ваш класс не содержит указателей или других объектов, где семантика копии по умолчанию не работает, тогда вам не нужно писать назначение копии вообще –

+0

Это вызовет оператор копирования (либо по умолчанию или переопределенная версия). Следовательно, применяются обычные оговорки о вызовах методов от конструкторов. В частности: не ожидайте, что какой-либо «виртуальный» будет работать так, как должен. – dhke

+0

Это меньше о том, что необходимо. Мне интересно, если и как это может работать – Qohelet

ответ

1

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

boost::math::geometric_distribution, похоже, не имеет конструктора по умолчанию. Вот почему вы получаете ошибку компилятора. Вы бы это исправить с помощью копирования конструктора geometric_distribution:

Testclass::Testclass(const Testclass& obj_ref) 
    : alpha(obj_ref.alpha), 
     geometricboost(obj_ref.geometricboost) 
{ 
} 

Согласно rule of three следует рассмотреть также осуществлять оператор копирования назначения (переместите конструктор перемещение оператора присваивания).

+0

Хорошо, понял. После добавления инициализации ошибки исчезли ... Но есть одна вещь, которая меня озадачивает. У меня было несколько классов - в некоторых из них произошла ошибка, как описано выше - в некоторых это не так. Хотя у них одни и те же члены и функции? Ошибки также зависят от использования класса. – Qohelet

1

Когда ваш конструктор копирования запускается, он сначала пытается инициализировать по умолчанию geometricboost (потому что вы не указали для него никакой инициализации) и только затем вызывает оператор присваивания. Это не работает, потому что геометрическое распределение не имеет конструктора по умолчанию.

Вам было бы лучше реализовать назначение из копии (используя копию, а затем заменить идиому), а не наоборот, как предложено в Calling assignment operator in copy constructor.

В качестве альтернативы вы можете просто полностью удалить свой конструктор копий - созданный компилятор будет работать нормально.

+0

На самом деле - появляется ли ошибка только в том случае, если требуется специальная инициализация? – Qohelet

+0

Да. Если все члены могут быть сконфигурированы по умолчанию, вы не получите ошибку из своего кода. Это не значит, что это хорошая идея. –

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