Jump to content
  • Advertisement
Sign in to follow this  
slayemin

[resolved] return values of a function

This topic is 3542 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Help! I'm stuck! I've been trying to figure out how to return an object from an overloaded class member function. It seems super simple, but I'm missing something. This is for a class I'm taking... Here is the professors sample code I'm using as reference: (link)
//----------------------------------  +  -------------------------------------
// overloaded +: addition of 2 Rationals, current object and parameter

Rational Rational::operator+(const Rational& a) const {
   Rational sum;

   sum.numerator = a.numerator * denominator + a.denominator * numerator;
   // same as:
   // sum.numerator = a.numerator * this->denominator
   //                 + a.denominator * this->numerator;

   sum.denominator = a.denominator * denominator;
   sum.reduce();

   return sum;
}



Here is my source code:
Poly Poly::operator+(const Poly &src) const
{
	Poly Temp;

	//loop through the array elements of the larger array
	for(int a=0;a<=((Last > src.Last)?Last:src.Last);a++)
	{
		if(Last >= a && src.Last >= a)
			Temp.setCoeff(ptrData[a]+src.ptrData[a],a);
		else if(Last <= a && src.Last >= a)
			Temp.setCoeff(src.ptrData[a],a);
		else if(src.Last <= a && Last >= a)
			Temp.setCoeff(ptrData[a],a);
	}
	
	return Temp;

}



The usage would be something like this:
Poly A(5,4), B(3,6), C;
C = A + B;
I *think* the professors sample code is wrong. The locally declared variable goes out of scope after the function exits and the memory is released for reuse by other programs. I checked it out thoroughly in the debugger and spent an hour trying to figure out whats going on. But, I really don't know and I'm tired of exhausting myself on this. Help? Guidance? tips? suggestions? I'd appreciate it... Edit: It may be of relevance to note that I dynamically allocate memory in the setCoeff() function. Do I lose that when the function exits? [Edited by - slayemin on January 12, 2009 12:49:33 AM]

Share this post


Link to post
Share on other sites
Advertisement
Yes, the object is destructed as soon as the function returns. But that's immaterial here (unless Poly is defined oddly). I'm hesitant to help more for homework, though what sort of errors you're encountering will help us provide good hints.

Share this post


Link to post
Share on other sites
I realize the homework hesitation part, so I'm trying not to ask for help with the implementation. Just a nudge in the right direction would be good enough :)

The problem is that when the Temp variable is returned, it has garbage data instead of the data which I was trying to return. Its because the class destructor is being called when the member function exits, which is happening before the function can return the object I created. How useless.

How do I pass the object before calling the destructor?

Share this post


Link to post
Share on other sites
You may want to do some research into the "rule of three". Understanding this rule will help explain what is happening in your code.
The C++ FAQ Lite is also a good source of information.

Share this post


Link to post
Share on other sites
If your Poly class has an array member that's a pointer to dynamically allocated memory, that won't get copied automatically when you make a copy (like when you return a local). You need to either write a copy constructor and assignment operator for the class, use a smart array that can copy itself, or else rewrite to not use an array.

Share this post


Link to post
Share on other sites
when it returns, it will create a temp object to transform. Add some output information into construct function, to help you understand well. like this:

class Poly
{
public:
Poly()
{ std::cout << "Poly construct now!" << std::endl; }
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Ernasty
If your Poly class has an array member that's a pointer to dynamically allocated memory, that won't get copied automatically when you make a copy (like when you return a local). You need to either write a copy constructor and assignment operator for the class, use a smart array that can copy itself, or else rewrite to not use an array.


This helped a lot. I figured out what I needed to do from this. I did have the operator= and copy constructor, but the operator= wasn't implemented yet. I guess these operators are dependent on each other like that.

...now I feel dumb but wiser...


Poly Poly::operator+(const Poly &src) const
{
//get the larger of the two arrays and then set the temp array to the larger one
//then add all the values from the smaller array into the temp array and return the result.
if(Last>src.Last)
{

Poly Temp(*this);
for(int a=0;a<=src.Last;a++)
Temp.setCoeff(ptrData[a]+src.ptrData[a],a);
return Temp;
}
else
{
Poly Temp(src);
for(int a=0;a<=Last;a++)
Temp.setCoeff(ptrData[a]+src.ptrData[a],a);
return Temp;
}
}

Share this post


Link to post
Share on other sites
Quote:
I *think* the professors sample code is wrong. The locally declared variable goes out of scope after the function exits and the memory is released for reuse by other programs.


The reason it doesn't matter is that the result is returned by value, and therefore copied. As long as copy construction, assignment and destruction work properly for a class, it can then basically follow all the same rules as a primitive type. If something would "look right" with an int, it should "look right" with any class type, too (making the copy construction, etc. work properly is the class implementor's job) - unless e.g. there is a reason that instances of the class should never be copied.

If you used std::vector for storage, of course, the built-in destructor, copy constructor and assignment operator would work just fine (unless there's other interesting stuff in your class that you haven't had to show yet). You also wouldn't need to store a .Last member explicitly (since you could just query the vector for its .size()). Actually, storing a size instead of a "last element index" makes a lot more sense anyway - the standard library works that way, consistently, for very good reasons.

Also, I would argue there's no reason to go through the class' own encapsulation in order to implement the other functionality. At least, not for something that simple; if you change how coefficient-setting works, you probably would have to rethink the summation procedure anyway.

Finally, the non-immediate operators (+, -, *, /) are usually implemented as non-members in terms of immediate ones (+=, -=, *=, /=). This allows for reusing the code without sacrificing efficiency (due to redundant copying).

With standard library tools, we could have something like:


Poly& Poly::operator+=(const Poly &src) {
std::vector<Element>& sdata = src.data;
// Ensure this has at least as many elements as src
data.resize(std::max(data.size(), sdata.size()));
// Sum the src elements with corresponding elements of this, overwriting
std::transform(sdata.begin(), sdata.end(), data.begin(), data.begin(), std::plus<Element>);
// Allow for operator chaining
return *this;
}

Poly operator+(const Poly& a, const Poly& b) {
return Poly(a) += b;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!