Thread: Trouble with overloading operators in a class with composition relationship

  1. #1
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164

    Trouble with overloading operators in a class with composition relationship

    Hello,

    I have been working on this code for a week. I have a point class I created and got everything working. Then I had to create a circle class from the point class. Originally I used an inheritance relationship, then I rewrote the code for a composition relationship. I got everything working in the circle class. Then, moved on to a cylinder class that has a composition relationship to the circle class. I finally have all the functions working in this class, with the exception of the cylinder calc functions that use a circle calc function. I think it is because I need to overload the '+' and '*' to perform their operation on the circle class function. So, I went looking in my textbook and the other four books I purchased for additional reference. And, none of them explain the operator overloading sufficiently to apply it to my need.

    If anyone can help me by explaining what the body of my operator overload functions should look like I would appreciate it.

    Here is my cylinderType class definition in my header file:
    Code:
    #ifndef H_CYLINDER
    #define H_CYLINDER
    
    #include "circleClass.h"
    
    class cylinderType: public circleType
    {
    	public:
    		cylinderType();
    		cylinderType(int xCoord, int yCoord, int radius, int height);
    
    		void setHeight(int height);
    		void setCylinder(int xCoord, int yCoord, int radius, int height);
    		void setRadius(int radius);
    		void setCircle(int xCoord, int yCoord, int radius);
    		void setPoint(int xCoord, int yCoord);
    		void getHeight(int & height);
    		void getCylinder(int & xCoord, int & yCoord, int & radius, int & height);
    		void getRadius(int & radius);
    		void getCircle(int & xCoord, int & yCoord, int & radius);
    		void getPoint(int & xCoord, int & yCoord);
    
    		cylinderType operator+(const cylinderType &) const;
    		cylinderType operator*(const cylinderType &) const;
    
    		double calcLateralSurfArea();
    		double calcVolume();
    		double calcArea();
    		double calcCircum();
    		
    		void whereAmI();
    		void printLateralSurfArea();
    		void printVolume();
    		void printHeight() const;
    		void printCylinder() const;
    		void printArea();
    		void printCircum();
    		void printRadius() const;
    		void printCircle() const;
    		void printPoint() const;
    		
    	private:
    		pointType point;
    		circleType circle;
    		int h;
    };
    
    #endif
    And, here is part of the cpp implementation file. I eliminated some of the functions to save space and they weren't part of the problem. My code does compile and work excluding the calc functions:
    Code:
    #include "cylinderClass.h"
    
    cylinderType cylinderType::operator +(const cylinderType & right) const
    {
    	cylinderType temp;
    	temp = ;
    }
    
    cylinderType cylinderType::operator *(const cylinderType & right) const
    {
    	cylinderType temp;
    }
    
    double cylinderType::calcLateralSurfArea()
    {
    	return (circle.calcCircum() * h);
    }
    
    double cylinderType::calcTotalSurfArea()
    {
    	int radius;
    	return (circle.calcCircum() * (circle.getRadius(radius) + h));
    }
    
    double cylinderType::calcArea()
    {
    	return (circle.calcArea());
    }
    
    double cylinderType::calcVolume()
    {
    	return (circle.calcArea() * h);
    }
    
    void cylinderType::printLateralSurfArea()
    {
    	cout << "The Lateral Surface Area of a cylinder with ";
    	circle.printRadius(); 
    	cout <<	" and a height of " << h << " is ";
    	calcLateralSurfArea();
    	cout << endl;
    }
    
    void cylinderType::printTotalSurfArea()
    {
    	cout << "The Total Surface Area of a cylinder with a radius of ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is "; 
    	calcTotalSurfArea();
    	cout << endl;
    }
    
    void cylinderType::printVolume()
    {
    	cout << "The Volume of a cylinder with ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is ";
    	calcVolume();
    	cout << endl;
    }
    I cannot figure out the operator overload function definition for this application from the reference books I have. They all use the private variables witin the class (private: int a, b; then the function definition uses: "temp.a = a + right.a; temp.b = b + right.b; return temp;" or something similar) I can't figure out how to apply that to my situation.

    Thanks.

  2. #2
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    I recognized a problem with my cylinder calc functions. In the calcVolume(), calcTotalSurfaceArea() and calcLateralSurfaceArea() functions I have removed "circle." from the return statments because they are already defined as a cylinder function.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Before you start writing operators, ask if the operators make sense in the first place. What does it mean to add a cylinder to another cylinder? What about multiplying a cylinder by another cylinder?

    I cannot figure out the operator overload function definition for this application from the reference books I have. They all use the private variables witin the class (private: int a, b; then the function definition uses: "temp.a = a + right.a; temp.b = b + right.b; return temp;" or something similar) I can't figure out how to apply that to my situation.
    When you have to implement operator+, I suggest also implementing operator+=, and then implementing operator+ in terms of operator+=. The reasoning is that operator+= is typically best as a member of the class, and it modifies the current object. operator+ is typically best as a non-member function. You could make it a friend function, but if operator+= exists, operator+ could be a non-member non-friend:
    Code:
    T operator+(const T& x, const T& y)
    {
        return T(x) += y;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    I guess I am not following...I am looking at, say: calcLateralSurfArea() and that mathematical formula is: 2* PI * r * h. which is the calcCircum() * h. That function isn't working - on my printLateralSurfArea() nothing does. So, in debugging I have come to the conclusion it is because I am using the '*' operator on a function and that isn't defined yet.

    So from there I am trying to create the operator function and have stalled.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I am looking at, say: calcLateralSurfArea() and that mathematical formula is: 2* PI * r * h. which is the calcCircum() * h
    What does calcCircum() return? From what I see it returns a double, thus there is no operator overloading needed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    Then what else is happening for me to not have the amount print when it is called. My calcCircum() prints a result but the calcLateralSurfArea() does not.

    Maybe my height isn't set right and therefore a '0'.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Since you want to use composition instead of inheritance, change:
    Code:
    class cylinderType: public circleType
    To:
    Code:
    class cylinderType
    Then what else is happening for me to not have the amount print when it is called. My calcCircum() prints a result but the calcLateralSurfArea() does not.
    I suspect that your calcLateralSurfArea() is not implemented correctly. As I pointed out in another thread you started, getX() type of functions tend to return a value. In your change, you have used a different idiom, namely to pass an argument by reference and use that argument as an output. As such, I guess that getRadius() from circleType returns void, so (circle.getRadius(radius) + h) is incorrect.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    With your explanation, I understand the error I am getting with the calcTotalSurfArea(). getRadius() returns a void and I need the int radius to perform the calculation. How do I work around this? it is a getter so it is a void. But, there isn't a defined variable member just for radius, I have it as part of the circleType circle member variable. Does this mean I need a separate circleType r member variable in cylinder so I can call it separately in these calculation functions?

    Code:
    void cylinderType::getRadius(int & radius)
    {
    	circle.getRadius(radius);
    }
    
    
    double cylinderType::calcTotalSurfArea()
    {
    	int radius;
    	return (calcCircum() * (getRadius(radius) + h));
    }
    I get '+' : illegal operand of type 'void'

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    How do I work around this? it is a getter so it is a void.
    One option is to change it such that your getters return values. If not, you have to resort to a more long winded way:
    Code:
    double cylinderType::calcTotalSurfArea()
    {
        int radius;
        getRadius(radius);
        return calcCircum() * (radius + h);
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    I guess I am really confused. This chapter talks about inheritance, composition, function overloading, the pointer *this, friend functions, operator overloading, function templates and class templates all in 49 pages. I must have everything mixed up and confused.

    All of the examples in the text have the getter functions as a void return. So, I concluded that getters and setters didn't return anything.

    I also thought that " derived class : base class " was necessary for both inheritance and composition. But composition included a base class type variable in the member variable list.

    I think I am really confused. This is an 8 week online class where it is really self study - read the book write the programs and take the tests. The instructor really doesn't. I have learned more about my code errors from this forum than I have in two weeks of emails with the instructor.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    All of the examples in the text have the getter functions as a void return. So, I concluded that getters and setters didn't return anything.
    As far as I know, there is no rule in the C++ standard that says that getters and setters must or must not return anything. This is all a matter of how you want to design your class' public interface. In fact, in many situations you may not want getters and setters at all.

    In this case, your getter does not return anything, so it cannot directly participate in your formula. You have to use it to get the radius value into the radius variable, and then have the radius variable participate in the formula.

    I also thought that " derived class : base class " was necessary for both inheritance and composition. But composition included a base class type variable in the member variable list.
    It is only necessary for inheritance. Where composition is not concerned with base classes or derived classes. It is merely concerned with classes and the members they own.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I also thought that " derived class : base class " was necessary for both inheritance and composition. But composition included a base class type variable in the member variable list.
    Composition:
    Code:
    class Door {};
    class Window {};
    class Car {
        Door door[4];
        Window window[4];
        Window windscreen;
    };
    Inheritance:
    Code:
    class Vehicle {};
    class Car : public Vehicle {};
    class Toyota : public Car {};
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    Thank You! You have explained a lot.

    I realize the more I do the more I will learn, but the class deadline is hanging over my head, and causing immeasureable stress. I am still on program 4 of lesson 1. Each lesson covers 2 or 3 chapters and has a test that includes 5 programs to be submitted. The programs are worth just 4 points each. So, I could realistically not write a line of code and pass the class. But that is not what I feel is in the best interest of learning data structures.

    Thank you laserlight, you have come to my aid again.

  14. #14
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    I am still having issues with my cylinder calc functions. I can't figure out what I am missing.

    These print out fine:
    Code:
    double cylinderType::calcArea()
    {
    	return (circle.calcArea());
    }
    
    void cylinderType::printArea()
    {
    	circle.printArea();
    }
    
    double cylinderType::calcCircum()
    {
    	return (circle.calcCircum());
    }
    
    void cylinderType::printCircum()
    {
    	circle.printCircum();
    }
    These print do not print the Volume, Total Surface Area, nor Lateral Surface Area and I can't find the problem. Any suggestions where to look?
    Code:
    double cylinderType::calcVolume()
    {
    	return (calcArea() * h);
    }
    
    void cylinderType::printVolume()
    {
    	cout << "The Volume of a cylinder with ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is ";
    	calcVolume();
    	cout << endl;
    }
    
    double cylinderType::calcTotalSurfArea()
    {
    	int radius;
    	getRadius(radius);
    	return (calcCircum() * (radius + h));
    }
    
    void cylinderType::printTotalSurfArea()
    {
    	cout << "The Total Surface Area of a cylinder with a radius of ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is "; 
    	calcTotalSurfArea();
    	cout << endl;
    }
    
    double cylinderType::calcLateralSurfArea()
    {
    	return (calcCircum() * h);
    }
    
    void cylinderType::printLateralSurfArea()
    {
    	cout << "The Lateral Surface Area of a cylinder with ";
    	circle.printRadius(); 
    	cout <<	" and a height of " << h << " is ";
    	calcLateralSurfArea();
    	cout << endl;
    }

  15. #15
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    	cout << "The Volume of a cylinder with ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is ";
    Might want to say something like "... a radius of ..." in there.

    Code:
    double cylinderType::calcVolume()
    {
    	return (calcArea() * h);
    }
    
    void cylinderType::printVolume()
    {
    	cout << "The Volume of a cylinder with ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is ";
    	calcVolume();
    	cout << endl;
    }
    calcVolume() returns the volume, it doesn't print it. You need to actually print the value, with something like
    Code:
    double cylinderType::calcVolume()
    {
    	return (calcArea() * h);
    }
    
    void cylinderType::printVolume()
    {
    	cout << "The Volume of a cylinder with ";
    	circle.printRadius();
    	cout << " and a height of " << h << " is " << calcVolume() << endl;
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bolean Operators hurt my head. (Trouble understanding) :(
    By Funcoot in forum C++ Programming
    Replies: 3
    Last Post: 01-20-2008, 07:42 PM
  2. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  3. Overloading compound operators?
    By Nyda in forum C# Programming
    Replies: 2
    Last Post: 04-28-2004, 05:42 AM
  4. Overloading operators...
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 11-21-2001, 08:24 PM
  5. Overloading Operators
    By Raven Arkadon in forum C++ Programming
    Replies: 1
    Last Post: 10-24-2001, 10:24 AM