Dynamic Array, Deep Copy -- Where to Allocate?

Hi,

I am not sure if should allocate data within the constructor of my object or when the copy constructor is invoked -- to use a deep copy of my data.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
        const int SIZE = 3;

	Polynomial p1 = Polynomial(SIZE);
        Polynomial p2 = Polynomial(SIZE);

	std::cout << "Initialize Polynomial Coefficients (1)" << std::endl;
	std::cin >> p1;

        std::cout << "Initialize Polynomial Coefficients (2)" << std::endl;
	std::cin >> p2;

        std::cout << std::endl;
        
	std::cout << "Adding pointers ";
	std::cout << p1 + p2 << std::endl;

        //...
        return 0;
}


At this line: Polynomial p1 = Polynomial(SIZE); the code proceeds to the constructor:

1
2
3
4
5
Polynomial::Polynomial(int size)
{
	this->size = size;
	this->m_Ptr = new double[this->size];
}


Where data is allocated with the respective size and type -- since data is allocated for p1, I can read data into the p1 object by overloading the insertion stream operator (>>):

1
2
3
4
5
6
7
8
std::istream& operator >>(std::istream &inputStream, const Polynomial &other)
{
	for (int i = 0; i < other.size; i++)
	{
		inputStream >> *(other.m_Ptr + i);
	}
	return inputStream;
}



What I want to know: is it possible to allocate my data using just the deep copy in the copy constructor and not in the constructor? For example, if I take the allocation out of the ctor and put it in the copy ctor:

1
2
3
4
5
6
7
8
9
10
11
12
Polynomial::Polynomial(int size)
{
	this->size = size;
	//this->m_Ptr = new double[this->size];
}

Polynomial::Polynomial(const Polynomial &other)
{
	this->size = other.size;
	this->m_Ptr = new double[this->size];
}


But if I do that (above) I am unable to read data into p1 in the >> overload. This is because p1 is not allocated until we reach this part of the code:

1
2
3
4
5
6
7
int main()
        //...
        std::cout << std::endl;
	std::cout << "Adding pointers ";
	std::cout << p1 + p2 << std::endl;

        return 0;



What only seems to work is allocating in both the ctor and copy ctor. But this results in unnecessary allocation, e.g., too much allocation. From what I researched a deep copy consists of allocating the data in my pointer (in this case). But the deep copy is only invoked when I overload operations such as +, -, or multiplication *.

So let's say I leave the allocation as is and decide to not care about allocation overhead. I cannot seem to correctly display the difference or multiplicative of the two objects from the overloads.

The below is just returning addresses:

1
2
3
4
5
6
7
8
9
const Polynomial Polynomial::operator -(const Polynomial &other) const
{
	const Polynomial * result = this;
	for (int i = 0; i < other.size; i++)
	{
		*(result->m_Ptr + i) = *(other.m_Ptr + i) - *(this->m_Ptr + i);
	}
	return *(result);
}


The below is just returning addresses:
1
2
3
4
5
6
7
8
9
const Polynomial Polynomial::operator *(const Polynomial &other) const
{
	const Polynomial * result = this;
	for (int i = 0; i < other.size; i++)
	{
		*(result->m_Ptr + i) = *(other.m_Ptr + i) * *(this->m_Ptr + i);
	}
	return *(result);
}


But adding them works just fine:
1
2
3
4
5
6
7
8
9
const Polynomial Polynomial::operator +(const Polynomial &other) const
{
	const Polynomial * result = this;
	for (int i = 0; i < other.size; i++)
	{
		*(result->m_Ptr + i) = *(other.m_Ptr + i) + *(this->m_Ptr + i);
	}
	return *(result);
}


I hope this has been coherent and that someone can help!
Last edited on
Topic archived. No new replies allowed.