Beispiellösung
Content |
#ifndef ARRAY_HPP #define ARRAY_HPP #include <algorithm> #include <cassert> #include <cstdlib> #include <new> #include <utility> template<typename T> class Array { private: using Tag = enum {AllocateStorage}; Array(Tag tag, std::size_t size) : size(size), data(size > 0? static_cast<T*>(operator new(sizeof(T) * size)) : nullptr) { } public: Array() : size(0), data(nullptr) { } Array(std::size_t size) : Array(AllocateStorage, size) { for (std::size_t index = 0; index < size; ++index) { new (data + index) T(); } } Array(std::size_t size, const T& t) : Array(AllocateStorage, size) { for (std::size_t index = 0; index < size; ++index) { new (data + index) T(t); } } Array(const Array& other) : Array(AllocateStorage, other.size) { for (std::size_t index = 0; index < size; ++index) { new (data + index) T(other.data[index]); } } friend void swap(Array& a1, Array& a2) { using std::swap; swap(a1.size, a2.size); swap(a1.data, a2.data); } Array(Array&& other) : Array() { swap(*this, other); } ~Array() { for (std::size_t index = 0; index < size; ++index) { data[index].~T(); } operator delete(data); } Array& operator=(Array other) { swap(*this, other); return *this; } std::size_t get_size() const { return size; } T& operator()(std::size_t index) { assert(index < size); return data[index]; } const T& operator()(std::size_t index) const { assert(index < size); return data[index]; } private: std::size_t size; T* data; }; #endif
#include <iostream> #include "array.hpp" int main() { Array<Array<double>> m(8); for (std::size_t i = 0; i < m.get_size(); ++i) { m(i) = Array<double>(m.get_size()); for (std::size_t j = 0; j < m(i).get_size(); ++j) { m(i)(j) = i + j; } } for (std::size_t i = 0; i < m.get_size(); ++i) { for (std::size_t j = 0; j < m(i).get_size(); ++j) { std::cout << " " << m(i)(j); } std::cout << std::endl; } }
theon$ g++ -Wall -o test-array test-array.cpp theon$ valgrind ./test-array ==2087== Memcheck, a memory error detector ==2087== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==2087== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==2087== Command: ./test-array ==2087== 0 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 9 3 4 5 6 7 8 9 10 4 5 6 7 8 9 10 11 5 6 7 8 9 10 11 12 6 7 8 9 10 11 12 13 7 8 9 10 11 12 13 14 ==2087== ==2087== HEAP SUMMARY: ==2087== in use at exit: 5,128 bytes in 1 blocks ==2087== total heap usage: 11 allocs, 10 frees, 78,472 bytes allocated ==2087== ==2087== LEAK SUMMARY: ==2087== definitely lost: 0 bytes in 0 blocks ==2087== indirectly lost: 0 bytes in 0 blocks ==2087== possibly lost: 5,128 bytes in 1 blocks ==2087== still reachable: 0 bytes in 0 blocks ==2087== suppressed: 0 bytes in 0 blocks ==2087== Rerun with --leak-check=full to see details of leaked memory ==2087== ==2087== For counts of detected and suppressed errors, rerun with: -v ==2087== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) theon$