Я рекомендую начать с несколько более простым кодом для изучения C++. В вашем коде есть несколько ошибок и проблем.
Первый, синтаксис. Array
является шаблоном класса , но не является именем типа и, следовательно, не может использоваться как возвращаемый тип. Вы должны дать полное имя, т.е.
template<typename T>
Array<T>& Array<T>::operator = (const Array<T>& source);
Однако в определении шаблона, имя шаблона можно использовать вместо полного имени, таким образом, вы можете также сказать (заметить разницу)
template<typename T>
Array<T>& Array<T>::operator = (const Array& source);
Второй, то логика. У многих классов есть назначение operator=(type const&other)
. Идея состоит в том, что значение *this
изменяется на значение other
. Возвращаемое значение должно быть *this
. Таким образом, в вашем случае (docu for std::memcpy
)
template<typename T>
Array<T>& Array<T>::operator = (const Array& other)
{
const auto alloc = other.width * other.height;
if(alloc != width*height) { // need to re-allocate?
if(buffer) delete[] buffer; // delete old memory
buffer = alloc? new T[alloc] : nullptr; // allocate new memory
}
width = other.width;
height= other.height;
if(alloc)
std::memcpy(buffer,other.buffer,sizeof(T)*alloc); // copy data
return*this;
}
Тем не менее, настоятельно рекомендуется избегать использования new
и delete
операторов. Их эффективное использование в безопасном и безопасном потоке и без утечек памяти (1) нетривиально и (2) лучшие альтернативы предоставляются библиотекой C++. Ваш код, например, утечки памяти и не может инициализировать buffer
до nullptr
в случае строительства по умолчанию (возможно, вызывает ошибку сегментации).
Вы можете сохранить данные в элементе данных std::vector<T>
, или у вас может быть std::unique_ptr<T[]>
. В последнем случае вы можете
template <typename T>
class Array
{
protected:
size_t width=0, height=0; // provide default values;
std::unique_ptr<T[]> buffer;
public:
Array() = default; // default constructor: empty
Array(Array&&) = default; // move constructor
Array&operator=(Array&&) = default; // move assignment
Array(Array const&other) // copy constructor
: width(other.width)
, height(other.height)
, buffer(other.buffer? new T[width*height]:nullptr)
{
if(buffer)
std::memcopy(buffer.get(),other.buffer.get(),width*height*sizeof(T));
}
Array&operator=(Array const&other) // copy assignment
{
const auto alloc = other.width * other.height;
if(alloc != width*height)
buffer.reset(alloc? new T[alloc]:nullptr);
width = other.width;
height= other.height;
if(alloc)
std::memcopy(buffer.get(),other.buffer.get(),alloc*sizeof(T));
return*this;
}
Array(size_t w, size_t h) // construct with given width & height
: width(w), height(h), buffer(w*h? new T[w*h]:nullptr)
{} // leave data uninitialised
// you don't need to explicitly declare a destructor
};
Обратите внимание на наличие конструктора перемещения и назначения. Они могут помочь сделать код с использованием Array<>
более эффективным.
Опубликовать [mcve], пожалуйста. Контекст важен. – Angew
Я подозреваю, что возвращаемое значение должно быть 'Array &' –
'Array & Array :: operator =' ... Что такое * первый * 'Array', который должен быть? –