Изучаю ООП в С++ и столкнулся с непонятной для меня проблемой.
Имеем такой небольшой код (
main.cpp):
#include <iostream>
#include "IntArray.h"
IntArray fillArray()
{
IntArray a(6);
a[0] = 6;
a[1] = 7;
a[2] = 3;
a[3] = 4;
a[4] = 5;
a[5] = 8;
return a;
}
int main()
{
IntArray a = fillArray();
std::cout << a << '\n';
return 0;
}
Получаю следующий вывод:
constructed 0x7ffcd4d430f0: 0 0 0 0 0 0 (size 6)
0x7ffcd4d430f0: 6 7 3 4 5 8
При возврате по значению, почему-то не срабатывет деструктор, а также не срабатывает конструктор копирования при копирующей инициализации объекта
a
в функции
main. При этом, есть ещё обычный конструктор:
explicit IntArray(int size) : m_size {size}, m_array {nullptr}
{
assert(m_size > 0 && "IntArray size should be a positive integer.");
m_array = new int[m_size] {0};
assert(m_array && "Allocate the memory when init.");
std::cout << "constructed:\n" << *this << " (size " << m_size << ")\n";
}
Заметьте что есть ключевое слово
explicit, тем самым я запрещаю использование этого конструктора для неявной конвертации. Также, мои конструктор копирования и перегруженный оператор присваивания выполняют
глубокое копирование. Вот весь код класса, если нужно:
IntArray.h
#ifndef INT_ARRAY_H
#define INT_ARRAY_H
#include <iostream>
#include <cassert>
class IntArray
{
private:
int m_size;
int* m_array;
public:
explicit IntArray(int size) : m_size {size}, m_array {nullptr}
{
assert(m_size > 0 && "IntArray size should be a positive integer.");
m_array = new int[m_size] {0};
assert(m_array && "Allocate the memory when init.");
std::cout << "constructed " << *this << " (size " << m_size << ")\n";
}
IntArray(const IntArray& arr);
~IntArray()
{
std::cout << "deleting... : " << *this << " (size " << m_size << ")\n";
delete[] m_array;
std::cout << this << " deleted\n";
}
void copyFrom(const IntArray& arr);
IntArray& operator= (const IntArray& arr);
int& operator[] (int index);
friend std::ostream& operator<< (std::ostream& out, const IntArray& avg);
};
#endif
IntArray.cpp
#include "IntArray.h"
IntArray::IntArray(const IntArray& arr)
{
copyFrom(arr);
std::cout << this << " copy constructed by: " <<
arr << " (size " << arr.m_size << ")\n";
}
IntArray& IntArray::operator= (const IntArray& arr)
{
std::cout << *this << "(size " << m_size <<
") assigment of: " << arr << " (size " << arr.m_size << ")\n";
if(this != &arr)
{
delete[] m_array;
copyFrom(arr);
}
std::cout << this << " now equals to " << arr << std::endl;
return *this;
}
void IntArray::copyFrom(const IntArray& arr)
{
m_size = arr.m_size;
if(arr.m_size > 1) // copy all values of arr to current m_array
{
m_array = new int[m_size];
assert(m_array && "Allocate the memory when copy.");
for(int i = 0; i < m_size; ++i)
m_array[i] = arr.m_array[i];
}
else // copy single value of arr to current m_array
m_array = new int {*arr.m_array};
}
int& IntArray::operator[] (int index)
{
assert(index >= 0 && index < m_size);
return m_array[index];
}
std::ostream& operator<< (std::ostream& out, const IntArray& avg)
{
out << &avg << ": ";
for(int i = 0; i < avg.m_size; ++i)
out << *(avg.m_array + i) << ' ';
return out;
}
Почему всё так, а не иначе?