Beispiellösung
Content |
#ifndef INTEGER_SEQUENCE_HPP #define INTEGER_SEQUENCE_HPP #include <cassert> #include <cstdlib> #include <new> #include <iostream> class IntegerSequence { public: IntegerSequence() : data(nullptr), size(0), allocated(0) { std::cout << "IntegerSequence: default constructor" << std::endl; } IntegerSequence(const IntegerSequence& other) : data( other.data? static_cast<int*>(std::malloc(other.allocated * sizeof(int))) : nullptr ), size(other.size), allocated(other.allocated) { if (size > 0 && !data) { throw std::bad_alloc(); } for (std::size_t i = 0; i < size; ++i) { data[i] = other.data[i]; } std::cout << "IntegerSequence: copy constructor copying " << size << " elements" << std::endl; } friend void swap(IntegerSequence& is1, IntegerSequence& is2) { std::cout << "IntegerSequence: swapping two sequences with " << is1.size << " and " << is2.size << " elements" << std::endl; std::swap(is1.data, is2.data); std::swap(is1.size, is2.size); std::swap(is1.allocated, is2.allocated); } IntegerSequence(IntegerSequence&& other) : IntegerSequence() { swap(*this, other); std::cout << "IntegerSequence: move constructor moving " << size << " elements" << std::endl; } ~IntegerSequence() { std::cout << "IntegerSequence: destructor deleting " << size << " elements" << std::endl; std::free(data); } IntegerSequence& operator=(IntegerSequence other) { std::cout << "IntegerSequence: assignment operator receiving " << other.size << " elements" << std::endl; swap(*this, other); return *this; } void add(int value) { if (size == allocated) { std::size_t newsize = allocated * 2 + 8; int* newdata = static_cast<int*>(std::realloc(data, newsize * sizeof(int))); if (!newdata) { throw std::bad_alloc(); } data = newdata; allocated = newsize; } data[size++] = value; } std::size_t length() const { return size; } int& operator()(std::size_t index) { assert(index < size); return data[index]; } const int& operator()(std::size_t index) const { assert(index < size); return data[index]; } private: int* data; std::size_t size; std::size_t allocated; }; #endif
#include <cstdlib> #include <iostream> #include "IntegerSequence.hpp" void print(const IntegerSequence& is) { for (std::size_t i = 0; i < is.length(); ++i) { std::cout << " " << is(i); } std::cout << std::endl; } IntegerSequence gen_sequence(IntegerSequence seq, int val) { for (int i = 1; i <= val; ++i) { seq.add(i); } return seq; } int main() { IntegerSequence iseq; // default constructor iseq.add(1); IntegerSequence iseq2{iseq}; // copy constructor iseq2.add(2); iseq = iseq2; // regular assignment operator std::cout << "iseq: "; print(iseq); IntegerSequence iseq3 = gen_sequence(iseq, 3); // move constructor std::cout << "iseq3: "; print(iseq3); IntegerSequence iseq4; iseq4 = gen_sequence(iseq, 3); // move assignment std::cout << "iseq4: "; print(iseq4); }
theon$ g++ -Wall -o test_is test_is.cpp theon$ wc -l ../step05/IntegerSequence.hpp IntegerSequence.hpp 97 ../step05/IntegerSequence.hpp 84 IntegerSequence.hpp 181 total theon$ valgrind ./test_is ==22654== Memcheck, a memory error detector ==22654== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==22654== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==22654== Command: ./test_is ==22654== --22654-- WARNING: Serious error when reading debug info --22654-- When reading debug info from /lib/amd64/ld.so.1: --22654-- Can't make sense of .data section mapping IntegerSequence: default constructor IntegerSequence: copy constructor copying 1 elements IntegerSequence: copy constructor copying 2 elements IntegerSequence: assignment operator receiving 2 elements IntegerSequence: swapping two sequences with 1 and 2 elements IntegerSequence: destructor deleting 1 elements iseq: 1 2 IntegerSequence: copy constructor copying 2 elements IntegerSequence: default constructor IntegerSequence: swapping two sequences with 0 and 5 elements IntegerSequence: move constructor moving 5 elements IntegerSequence: destructor deleting 0 elements iseq3: 1 2 1 2 3 IntegerSequence: default constructor IntegerSequence: copy constructor copying 2 elements IntegerSequence: default constructor IntegerSequence: swapping two sequences with 0 and 5 elements IntegerSequence: move constructor moving 5 elements IntegerSequence: assignment operator receiving 5 elements IntegerSequence: swapping two sequences with 0 and 5 elements IntegerSequence: destructor deleting 0 elements IntegerSequence: destructor deleting 0 elements iseq4: 1 2 1 2 3 IntegerSequence: destructor deleting 5 elements IntegerSequence: destructor deleting 5 elements IntegerSequence: destructor deleting 2 elements IntegerSequence: destructor deleting 2 elements ==22654== ==22654== HEAP SUMMARY: ==22654== in use at exit: 5,128 bytes in 1 blocks ==22654== total heap usage: 7 allocs, 6 frees, 77,992 bytes allocated ==22654== ==22654== LEAK SUMMARY: ==22654== definitely lost: 0 bytes in 0 blocks ==22654== indirectly lost: 0 bytes in 0 blocks ==22654== possibly lost: 5,128 bytes in 1 blocks ==22654== still reachable: 0 bytes in 0 blocks ==22654== suppressed: 0 bytes in 0 blocks ==22654== Rerun with --leak-check=full to see details of leaked memory ==22654== ==22654== For lists of detected and suppressed errors, rerun with: -s ==22654== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) theon$ ../step05/test_is >previous-output.txt theon$ ./test_is >updated-output.txt theon$ diff -U 2 previous-output.txt updated-output.txt --- previous-output.txt 2022-11-15 23:09:38.324814267 +0100 +++ updated-output.txt 2022-11-15 23:09:38.337554209 +0100 @@ -1,7 +1,12 @@ IntegerSequence: default constructor IntegerSequence: copy constructor copying 1 elements -IntegerSequence: assignment operator copying 2 elements +IntegerSequence: copy constructor copying 2 elements +IntegerSequence: assignment operator receiving 2 elements +IntegerSequence: swapping two sequences with 1 and 2 elements +IntegerSequence: destructor deleting 1 elements iseq: 1 2 IntegerSequence: copy constructor copying 2 elements +IntegerSequence: default constructor +IntegerSequence: swapping two sequences with 0 and 5 elements IntegerSequence: move constructor moving 5 elements IntegerSequence: destructor deleting 0 elements @@ -9,6 +14,9 @@ IntegerSequence: default constructor IntegerSequence: copy constructor copying 2 elements +IntegerSequence: default constructor +IntegerSequence: swapping two sequences with 0 and 5 elements IntegerSequence: move constructor moving 5 elements -IntegerSequence: move assignment taking 5 elements +IntegerSequence: assignment operator receiving 5 elements +IntegerSequence: swapping two sequences with 0 and 5 elements IntegerSequence: destructor deleting 0 elements IntegerSequence: destructor deleting 0 elements theon$ : theon$