Hello,

I'm trying to understand some things about derived classes: how to add something "extra" to existing functions in base class.
My base class is "shape2D" like a rectangle, 3 functions: set values, calculate, show results. No problem here.
Then I create a derived class named "shape3D". Please note the private stuff in the base class.
Everything goes OK when I create one object of shape2D, do stuff, then another object of shape3D and do the same stuff. I get no errors for the private variables from the base class.
Then I want to add another dimension (height) to the derived class and add one more cin for it in the first function (set third value), one more calculation in the second function (calculate volume), one more line in the third function (display volume). Here I get the errors that "cannot access private member". If I switch variables from private to protected works OK. See class shape2D.h.

I don't understand why it works with private vars if I don't modify the methods and why should I use protected in the other case.
Do I miss something? Can someone explain how this works (shortly, I couldn't find a proper explanation on goolge).
Is this "add 2 lines to the base function" (class "shape3D") OK?

Code below. I work with separate files just for "training" purposes.

Thank you!

shape2D.h:

#ifndef SHAPE2D_H
#define SHAPE2D_H

using namespace std;

class shape2D
{
public:
    shape2D();
    virtual ~shape2D();
    void set_dimensions();
    void dimension_calculations();
    void show_results();

protected:
    //int d_lenght,d_width,d_area, d_perimeter;  //Here I switch
private:
    int d_lenght,d_width,d_area, d_perimeter;  // with this
};

#endif // SHAPE2D_H

shape2D.cpp:

#include <iostream>
#include ".\shape2D.h"

shape2D::shape2D()
{
}

shape2D::~shape2D()
{
}

void shape2D::set_dimensions()
{
    cout << "Lenght : ";
    cin >> d_lenght;
    cout << "Width : ";
    cin >> d_width;
}

void shape2D::dimension_calculations()
{
    d_perimeter = 2 * (d_lenght + d_width);
    d_area = d_lenght * d_width;
}

void shape2D::show_results()
{
    cout << "\n\nPerimeter: \t" << d_perimeter << "\nArea: \t\t" << d_area << endl;
}

main:

#include <iostream>
#include "shape2D.h"
#include "shape3D.h"

using namespace std;

int main()
{
    shape2D sh2d;
    shape3D sh3d;

    sh2d.set_dimensions();
    sh2d.dimension_calculations();
    sh2d.show_results();

    cout << "/n/n/n/n";

    sh3d.set_dimensions();
    sh3d.dimension_calculations();
    sh3d.show_results();

    return 0;
}

shape3D.h:

#ifndef SHAPE3D_H
#define SHAPE3D_H

#include "shape2D.h"
#include <iostream>

class shape3D:public shape2D
{
public:
    shape3D();
    virtual ~shape3D();
    /*void set_dimensions(); // I TRIED TO "IMPROVE" BASE CLASS FUNCTION
    void dimension_calculations();
    void show_results();*/
protected:
    int d_height, d_volume;
private:
    //int d_height, d_volume;
};

#endif // SHAPE3D_H

shape3D.cpp:

#include "shape3D.h"

shape3D::shape3D()
{
    //constructor
}

shape3D::~shape3D()
{
    //destructor
}

// I TRIED TO "IMPROVE" BASE CLASS FUNCTION

/*void shape3D::set_dimensions()
{
    shape2D::set_dimensions(); //CALLING THE BASE FUNCTION THEN ADD ONE MORE INPUT
    cout << "Height : ";
    cin >> d_height;
}

void shape3D::dimension_calculations()
{
    shape2D::dimension_calculations();
    d_volume=d_height*d_lenght*d_width;
}

void shape3D::show_results()
{
    shape2D::show_results();
    cout << "Volume: \t" << d_volume;
}
*/

I don't understand why it works with private vars if I don't modify the methods and why should I use protected in the other case.

private: means the derived class cannot access the variable -- if the defived class doesn't attempt to access the private member then there is no problem or error. There's a couple ways you can handle that.

  • Change the variables from private to protected
  • In the base class add get and set functions

Edited 2 Years Ago by Ancient Dragon

I know what private and protected means. I just didn't get the point that if I'm using them as they are is kinda OK, but not OK once I try to alter them.
I also understand that using protected everything goes OK.

What I'm not so sure about is in this part:

void shape3D::set_dimensions()
{
    shape2D::set_dimensions(); //CALLING THE BASE FUNCTION THEN ADD ONE MORE INPUT
    cout << "Height : ";
    cin >> d_height;
}

As I understood, the line shape2D::set_dimensions(); is calling the base class' set_dimensions(); function, which is public. And calling a public member should not throw an error. But it is, saying that a private var (d_lenght) in shape2D cannot be accessed because is private. Of course is private, but it is only accessed by the function which is public, inside the class. It is not directly accessed by the derived class, but calling the public function.

All I need is to understand the logic behind this.

Can you please be more explicit with set and get functions? Is it something like the following?

class a
{
    public:
        a();
        virtual ~a();
        void set_value(int x);
        int get_value();
    private:
        int y;
};

void a::set_value(int x)
{
    y=x;
}

int a::get_value()
{
    return y;
}

Thanks!

But it is, saying that a private var (d_lenght) in shape2D cannot be accessed because is private.

I think you misunderstood the error message. It means that Shape3D can't access private members of the base class. It's complaining about the line cin >> d_height; that appears in shape3D::set_dimensions().

Can you please be more explicit with set and get functions?

Yes, you explained it yourself perfectly, although normally they would be written as inline methods, but the way you have them is ok too.

class a
{
    public:
        a();
        virtual ~a();
        void set_value(int x) {y=x;}
        int get_value() {return y;}
    private:
        int y;
};

Edited 2 Years Ago by Ancient Dragon

I think you misunderstood the error message. It means that Shape3D can't access private members of the base class. It's complaining about the line cin >> d_height; that appears in shape3D::set_dimensions().

That's what I wanted to say :)

Just tested the set and get and it works good.

Thank you for your help!

Best regards

Oops.. I forgot to ask about "improving" base class' functions. What would be the best way to add something?
Like in my shape2D::set_dimensions for width and lenght, I want to add the third dimension height in the derived class shape3D. Is it possible to do it or should I use virtual function in the base class and set everything up in the derived class?
I think of creating a 3rd level derivation and to add the 4th dimension. It would be nice to have something like just adding another line of code to the existing lines (in parent class).

You would make the fuction virtual, which allows you to override the behavior of a function when defining the child class. It should be as simple as changing void set_dimensions() as virtual void set_dimensions() in your shape2D class, and then rewriting shape3D::set_dimensions() to accept all three dimensions.

There may also be a way to call overridden virtual functions in a child class, but it's been so long and I have so little use for it that I don't remember how to use that feature anymore.

Edited 2 Years Ago by Tumlee

This question has already been answered. Start a new discussion instead.