LINUX.ORG.RU

Использование placement new

 


0

3

Помогите разобраться с заданием:

В предыдущей версии предполагается, что для типа T определен оператор присваивания или он ему не нужен (например, для примитивных типов он не нужен). При создании шаблонных классов контейнеров (вроде Array и не только) разумно стараться минимизировать требования к типам шаблонных параметров. Поэтому усложним задачу, реализуйте класс Array не полагаясь на то, что для типа T определен оператор присваивания. Hints: используйте placement new и явный вызов деструктора, чтобы создавать и уничтожать объекты, аллоцировать правильно выровненную память можно с помощью new char[N * sizeof(T)], где N - количество элементов массива.

#include <cstddef>

template <typename T>
class Array
{
    // Список операций:
    //
    // Array(size_t size, const T& value = T())
    //   конструктор класса, который создает
    //   Array размера size, заполненный значениями
    //   value типа T. Считайте что у типа T есть
    //   конструктор, который можно вызвать без
    //   без параметров, либо он ему не нужен.
    //
    // Array()
    //   конструктор класса, который можно вызвать
    //   без параметров. Должен создавать пустой
    //   Array.
    //
    // Array(const Array &)
    //   конструктор копирования, который создает
    //   копию параметра. Для типа T оператор
    //   присвивания не определен.
    //
    // ~Array()
    //   деструктор, если он вам необходим.
    //
    // Array& operator=(...)
    //   оператор присваивания.
    //
    // size_t size() const
    //   возвращает размер массива (количество
    //                              элемнтов).
    //
    // T& operator[](size_t)
    // const T& operator[](size_t) const
    //   две версии оператора доступа по индексу.
};

Вот моё решение:

template <typename T>
class Array
{
public:
    explicit Array(size_t size = 0, const T& value = T())
        :size_(size), data(new T[size])
    {
        for (int i=0; i<size; i++)
            data[i] = value;
    }
    //Array():size_(0), data(new T[0]) {}

    Array(const Array &arrayToCopy)
    {
        size_ = arrayToCopy.size();
        data = static_cast<T*>(operator new[] (size_ * sizeof(T)));
        for ( int i = 0; i < size_; ++i)
            data[i] = arrayToCopy[i];
    }
    ~Array()
    {
        for (int i = 0; i < size_; i++)
          {
              data[i].~T();
          }
        operator delete[](data);
    }

    Array& operator=(const Array & right)
    {
        size_=right.size();
        char * buff = new char[size_ * sizeof(T)];
        data = new (buff) T[size_];
        for (int i=0; i< size_; ++i)
            data[i]=right[i];
        return *this;
    }
    size_t size() const
    {
        return size_;
    }
    T& operator[](size_t i)
    {
        return data[i];
    }
    const T& operator[](size_t i) const
    {
        return data[i];
    }
private:
    size_t size_;
    T * data;
};

А вот выхлоп:

Compilation error main.cpp: In instantiation of ‘Array<T>::Array(size_t, const T&) [with T = Trace; size_t = long unsigned int]’: main.cpp:188:23: required from here main.cpp:177:9: error: ‘Trace& Trace::operator=(const Trace&)’ is private main.cpp:114:13: error: within this context main.cpp: In instantiation of ‘Array<T>& Array<T>::operator=(const Array<T>&) [with T = Trace; Array<T> = Array<Trace>]’: main.cpp:192:11: required from here main.cpp:177:9: error: ‘Trace& Trace::operator=(const Trace&)’ is private main.cpp:140:13: error: within this context main.cpp: In instantiation of ‘Array<T>::Array(const Array<T>&) [with T = Trace; Array<T> = Array<Trace>]’: main.cpp:195:28: required from here main.cpp:177:9: error: ‘Trace& Trace::operator=(const Trace&)’ is private main.cpp:123:13: error: within this context

Подскажите где ошибка?

★★

Ответ на: комментарий от Pirr

Спасибо за отклик на просьбы. Если появится решение той задачи - сбрось сюда. Хотелось бы все-таки посмотреть где утечка памяти

general1
()
Ответ на: комментарий от general1

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

mikemiem
()
23 октября 2015 г.

Для тех, кто проходит курс в 2015 году

#include <cstddef>

template <typename T>
class Array
{
public:
    explicit Array(size_t size = 0, const T& value = T())
        : data_(static_cast<T*>(operator new[](size * sizeof(T))))
        , size_(size) {
        for(int i = 0; i != size; ++i)
            new (data_ + i) T(value);
    }
    
    Array(const Array &a)
		: data_(static_cast<T*>(operator new[](size_ * sizeof(T))))
		, size_(a.size()) {
		for (int i = 0; i != size_; ++i)
			//data_[i] = a.data_[i];
            new (data_ + i) T(a[i]);
	}
    
    ~Array() {
        for(int i = 0; i != size_; ++i)
            data_[i].~T();
        operator delete[] (data_);
    }
    
    Array& operator=(const Array & a) {
		if (this != &a) {
            operator delete [] (data_);
			size_ = a.size();
			data_ = static_cast<T*>(operator new[](size_ * sizeof(T)));
			for (int i = 0; i != size_; ++i)
                new (data_ + i) T(a[i]);
        }
		return *this;
	}
    
    size_t size() const { return size_; }
    
    //   две версии оператора доступа по индексу.
    T& operator[](size_t i) { return data_[i]; }
    const T& operator[](size_t i) const { return data_[i]; }
private:
    size_t    size_;
    T *       data_;
};
TekhnoLife
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.