K
K
klajowski2021-07-07 18:01:32
C++ / C#
klajowski, 2021-07-07 18:01:32

Why didn't the copy constructor and destructor get called?

I'm learning OOP in C++ and ran into a problem I don't understand.
We have such a small code ( 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;
}

I get the following output:
constructed 0x7ffcd4d430f0: 0 0 0 0 0 0  (size 6)
0x7ffcd4d430f0: 6 7 3 4 5 8

When returning by value, for some reason the destructor does not work, and the copy constructor does not work when copying the initialization of the object ain the main function . At the same time, there is also a regular constructor:
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";
}

Note that there is an explicit keyword , so I forbid the use of this constructor for implicit conversion. Also, my copy constructor and overloaded assignment operator perform a deep copy . Here is the entire class code, if needed:

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;
}


Why is everything so and not otherwise?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question