Thread: Problem with functions in inherited classes

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    8

    Problem with functions in inherited classes

    Here is what I'm trying to do.

    I have 3 classes:

    base
    |
    derived1
    |
    derived2

    In the main program, I call a function within the base class that sets 2 variables. In the derived class, I have a function that calls on a function within the base class to retrieve and return those variables.

    The problem I'm having is that it is not working right, or I'm doing something wrong. What seems to be happening, is that when the function in the derived class calls the base class function, rather than just running, it first seems to run the default constructor, which zeros out the stored variables. Then the function returns the zeros.

    Does that make sense? I'm new to C++ so I may be missing something, but from what I've read, in theory, this should work.

    Why is it calling the default constructor first?

    Any help would be greatly appreciated.

    Thanks.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Generally it is best to post the simplest and smallest complete program that demonstrates the behavior. In this case, it might as simple as showing us the line of code where the derived class calls the base class function, but whatever code you can provide would help.

  3. #3
    Registered User
    Join Date
    Aug 2009
    Posts
    8
    I tried to keep the code I'm posting as limited as possible. I'm posting the base class and one of the derived classed as defined in the header files, the default constructor for the base class and the one function in the derived class that is calling on the base class function.

    base class header file:
    Code:
    class pointType
    {
    public:
    	  static void setPoints(double pointX, double pointY);
    	    
    	  void print() const;
    	    
    	  double getX() const;
    	    
    	  double getY() const;
    	    
    	  pointType();
    	    
    	  pointType(double pointX, double pointY);
    	    
    private:
    	  static double x, y;
    };
    Base class constructor:
    Code:
    pointType::pointType()
    {
    	x = 0;
    	y = 0;
    }
    derived class header file:
    Code:
    class circleType: public pointType
    {
    
    public:
    		static void setRadius(double cRadius);
    
    		void print() const;
    
    		double getRadius() const;
    
    		double calcArea() const;
    
    		double calcCir() const;
    
    		double calcDia() const;
    
    		circleType ();
    
    		circleType(double cRradius);
    
    private:
    		static double radius;
    };
    derived class function:
    Code:
    void circleType::print() const     //Prints the radius, diameter, area and circumference
    {
    	cout << "The radius of the circle is: " << getRadius() << endl;
    	cout << "The diameter of the circle is: " << calcDia() << endl;
    	cout << "The area of the circle is: " << calcArea() << endl;
    	cout << "The circumference of the circle is: " << calcCir() << endl;
    	cout << fixed << setprecision(2) << "The x and y coordinates are: ";
    	cout << getX() << "," << getY() << "." << endl;
    }

    Thanks.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, I'm still not sure exactly what's going on. If you think the base constructor is getting called, the easy way to see if that's true is to put a print statement (or other moral equivalent) inside the constructor and see. I don't see any reason, looking at this print() function, to expect the constructor to be called.

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    8
    I did test it by changing the values of my default constructor to something other than 0 and the new numbers then showed up. Something isn't right, I just don't know what or where.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Looking at what you've got again, and looking at the original problem again, I will agree that the base constructor is run -- the base constructor is always run, first, before a derived object is constructed. I don't see any derived-class methods that can change the values of x and y, nor for that matter do I see any base-class methods, save the two-argument constructor (which presumably would not be called by the zero-argument derived-class constructor). So how do you expect this x and y to change?

  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    8
    Like I said, I'm a c++ newbie.

    In the main program, I have user input set x and y. I thought that x and y would not change, so that when I called the "get" functions from the derived class, it would return the stored user input. I didn't know that it would run the default constructor and cause x and y to change.

    What can I do to prevent that from happening? I want whatever is input for x and y by the user to stay and be able to be called by the derived classes functions.

    Thanks.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by cableguy414 View Post
    Like I said, I'm a c++ newbie.

    In the main program, I have user input set x and y. I
    Well, okay, but how? The variables are private and static -- static meaning that there's only one copy of them, ever, throughout the entire program, no matter how many objects you make, and private meaning you can't actually get to them from the program (the objects themselves are the only things that can access them).

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    A constructor should not be setting static values. A constructor initializes a single instance of an object. A static member variable exists and is shared between all instances of the object.

    It looks like your problem is that your variables are static.

  10. #10
    Registered User
    Join Date
    Aug 2009
    Posts
    8
    Ok, I removed all of the "statics" and I removed the =0 from the default constructors.

    And it is still returning zero when I call the getX and getY functions, but only when they're called from the derived class. When they're called from within the base class they return the correct information.

    I'm going to apologize in advance if this is too much, but I am going to post all of my code. I'm getting desperate.

    Main .cpp
    Code:
    #include "pointType.h"
    #include "circleType.h"
    #include "cylinderType.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    
            pointType point;
    
            double x, y;
    
    	cout << "Enter the x-coordinate: ";
    	cin >> x;
    
    	cout << "Enter the y-coordinate: ";
    	cin >> y;
    
    	point.setPoints(x, y);
    	point.print();
    
    	circleType circle;
    
            double r;
    
    	cout << "Enter the radius of the circle: ";
    	cin >> r;
    
            circle.setRadius(r);
    	circle.print();
    
    	cylinderType cylinder;
    
    	double h;
    
    	cout << "Enter the height of the cylinder: ";
    	cin >> h;
    
    	cylinder.setHeight(h);
    	cylinder.print();
    
        return 0;
    }
    base class .h
    Code:
    #ifndef H_PointType
    #define H_PointType
    
    using namespace std;
    
    class pointType
    {
    public:
      
    	  void setPoints(double pointX, double pointY);
    
    	  void print() const;
    
    	  double getX() const;
    
    	  double getY() const;
    
    	  pointType();
    
    	  pointType(double pointX, double pointY);
    
    private:
    
    	  double x, y;
    
    };
    
    #endif
    base class .cpp
    Code:
    #include "pointType.h"
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    void pointType::setPoints(double pointX, double pointY)
    {
    	x = pointX;
    	y = pointY;
    }
    
    void pointType::print() const
    {
    	cout << fixed << setprecision(2) << "The x and y coordinates are: ";
    	cout << getX() << "," << getY() << "." << endl;
    }
    
    double pointType::getX() const
    {
    	return x;
    }
    
    double pointType::getY() const
    {
    	return y;
    }
    
    pointType::pointType()
    {
    	x;
    	y;
    }
    
    pointType::pointType(double pointX, double pointY)
    {
    	x = pointX;
    	y = pointY;
    }
    derived class 1 .h file
    Code:
    #ifndef H_CircleType
    #define H_CircleType
    
    #include "pointType.h"
    
    using namespace std;
    
    class circleType: public pointType
    {
    
    public:
    
    		void setRadius(double cRadius);
    
    		void print() const;
    
    		double getRadius() const;
    
    		double calcArea() const;
    
    		double calcCir() const;
    	
    		double calcDia() const;
    	
    		circleType ();
    	
    		circleType(double cRradius);
    	
    private:
    
    		double radius;
    
    };
    
    #endif
    derived class1 .cpp file
    Code:
    #include "circleType.h"
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    
    using namespace std;
    
    void circleType::setRadius(double cRadius)
    {
    	radius = cRadius;
    }
    
    void circleType::print() const
    {
    	cout << "The radius of the circle is: " << getRadius() << endl;
    	cout << "The diameter of the circle is: " << calcDia() << endl;
    	cout << "The area of the circle is: " << calcArea() << endl;
    	cout << "The circumference of the circle is: " << calcCir() << endl;
    	cout << fixed << setprecision(2) << "The x and y coordinates are: ";
    	cout << getX() << "," << getY() << "." << endl;
    }
    
    double circleType::getRadius() const
    {
    	return radius;
    }
    
    double circleType::calcArea() const
    {
    	double pi = 3.14159;
    	return (pi * (radius * radius));
    }
    
    double circleType::calcCir() const
    {
    	double pi = 3.14159;
    	return (calcDia() * pi);
    }
    
    double circleType::calcDia() const
    {
    	return radius * 2;
    }
    
    circleType::circleType()     //Default construtor
    {
    	radius;
    }
    
    circleType::circleType(double cRadius)
    {
    	radius = cRadius;
    }
    derived class2 .h file
    Code:
    #ifndef H_CylinderType
    #define H_CylinderType
    
    #include "circleType.h"
    
    using namespace std;
    
    class cylinderType: public circleType
    {
    
    public:
    
    	void setHeight(double cHeight);
    	
    	void print() const;
    
    	double getHeight() const;
    
    	double calcVolume()const;
    
    	double calcSurface() const;
    
    	cylinderType();
    
    	cylinderType(double cHeight);
    
    private:
    
    	double height;
    
    };
    
    #endif
    derived class2 .cpp file
    Code:
    #include "cylinderType.h"
    #include <iostream>
    #include <cmath>
    #include <iomanip>
    
    using namespace std;
    
    void cylinderType::setHeight(double cHeight)
    {
    	height = cHeight;
    }
    
    void cylinderType::print() const
    {
    	cout << "The height of the cylinder is: " << getHeight() << endl;
    	cout << "The radius of the cylinder base is: " << getRadius() << endl;
    	cout << "The volume of the cylinder is: " << calcVolume() << endl;
    	cout << "The surface area of the cylinder is: " << calcSurface() << endl;
    	cout << fixed << setprecision(2) << "The x and y coordinates are: ";
    	cout << getX() << "," << getY() << "." << endl;
    }
    
    double cylinderType::getHeight() const 
    {
    	return height;
    }
    
    double cylinderType::calcVolume() const
    {
    	double pi = 3.14159;
    	return (height * pi) * (getRadius() * getRadius());
    }
    
    double cylinderType::calcSurface() const
    {
    	double pi = 3.14159;
    	return (2 * calcArea()) + (calcCir() * height);
    }
    
    cylinderType::cylinderType()
    {
    	height;
    }
    
    cylinderType::cylinderType(double cHeight)
    {
    	height = cHeight;
    }

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's because you don't understand the implications of classes. Each class you create is an instance, just like each car is its own from a blueprint.
    Each instance has its own variables and data. That circleType may be derived from another class doesn't change this fact.
    What you are doing is creating one object first, assigning it data, creating a new object later and assigning it some other data. The second object will obviously not have the data of the first object.
    That A is derived from B usually means that B is also A. So if you create something of B, your circleType, it will also have all the members and data of A. So create only a circleType and give it the data.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Aug 2009
    Posts
    8
    I knew that each time the class is called, it makes a new implementation of it, that's why I though the static keyword would work. I though it would keep the x and y variables in memory so they can be accessed later.

    Unfortunately, I need to keep this file structure because it is part of a class project. And I thought the whole point of classes and separate files was so that I would not need to duplicate code.

    What do I need to do, either in the classes or in the main program to be able to have the user entered information (x and y points, and circle radius) remain available to be retried by functions in other classes.

    I need the circle class to be able to retrieve the x and y points and I need the cylinder class to be able to retrieve and use the radius.

    Thanks.

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by cableguy414 View Post
    I knew that each time the class is called, it makes a new implementation of it, that's why I though the static keyword would work. I though it would keep the x and y variables in memory so they can be accessed later.

    Unfortunately, I need to keep this file structure because it is part of a class project. And I thought the whole point of classes and separate files was so that I would not need to duplicate code.

    What do I need to do, either in the classes or in the main program to be able to have the user entered information (x and y points, and circle radius) remain available to be retried by functions in other classes.

    I need the circle class to be able to retrieve the x and y points and I need the cylinder class to be able to retrieve and use the radius.

    Thanks.
    Then why have a point object and a circle object at all? (I mean, yes you need the classes, but I don't see that you need to instantiate them by themselves, ever.) Just declare a Cylinder object, ask for all your stuff, and you're good to go.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by cableguy414 View Post
    And I thought the whole point of classes and separate files was so that I would not need to duplicate code.
    That's not the point of classes.
    You can write normal functions with code, too, and even separate them in files, if you want.
    The point of classes is to make an "object", like a car from a blueprint and then treat the objects as such, hence the name Object-Oriented Programming.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Aug 2009
    Posts
    8
    Ok, I got it working.

    First, thank you everyone for your help and advice. I was not resending the user input for x, y, and the radius with each call.

    Here's what I ended up doing.

    In the derived class:

    Code:
    circleType::circleType(double pointX, double pointY, double cRadius)     //Constructor with parameters
    {
    	pointType::setPoints(pointX, pointY);
    	radius = cRadius;
    In main:

    Code:
    circle.setRadius(x, y, r);
    There might be a better way of doing this, possibly as helios suggested, but I'm going to stick with this method for now. It works and I found it in my text book...

    Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Constructor problem in list of classes
    By G4B3 in forum C++ Programming
    Replies: 17
    Last Post: 06-01-2009, 03:13 AM
  2. Classes and Global Functions
    By d_heyzie in forum C++ Programming
    Replies: 4
    Last Post: 04-17-2007, 07:57 PM
  3. problem w/ color functions && win98 :P
    By DarkMortar in forum C Programming
    Replies: 2
    Last Post: 06-07-2006, 04:45 PM
  4. Classes and member functions
    By uraliss in forum C++ Programming
    Replies: 2
    Last Post: 04-13-2006, 07:38 AM
  5. help with classes and member functions
    By syner in forum C++ Programming
    Replies: 4
    Last Post: 07-19-2002, 08:45 PM