Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ class access level

Suppose I have two classes. One called Point:

class Point{
    public:
        Point(): x_(0), y_(0) {}
    protected: 
        int x_, y_;
    };

Then I have another class, which derives from Point:

class Point3D : public Point {
public:
    Point3D(): Point(), z_(0){}
    double distance(Point3D pt, Point base) const;
protected:
    int z_;
};

double Point3D::distance(Point3D pt, Point base) const
{
    int dist_x, dist_y;
    dist_x = base.x_ - x_;
    dist_y = base.y_ - y_;

    return sqrt(dist_x * dist_x +
                dist_y * dist_y);
}

Then I got error like: base.x_ is protected within this context. But the access level of Point3D to Point is public, plus the x_ data member in Point is protected. So it is supposed to be error-free, right? Can someone please help me clear this out?

like image 600
J. Lin Avatar asked Nov 09 '16 23:11

J. Lin


People also ask

What is access specifier C?

The public keyword is an access specifier. Access specifiers define how the members (attributes and methods) of a class can be accessed. In the example above, the members are public - which means that they can be accessed and modified from outside the code.

Which access level is used in C Plus Plus?

There are three of them available in C++: public, protected and private. The default access level for class members is private. To change the access level for a section of code, an access modifier is used followed by a colon.

How many access specifier are there in C?

In C++, there are 3 access modifiers: public. private. protected.

Are there access modifiers in C?

Master C and Embedded C Programming- Learn as you go Access Modifiers are used to implement data hiding in object oriented programming. There are three types of access modifiers used in C++. These are public, private and protected.


2 Answers

But the access level of Point3D to Point is public

That is not entirely true. The protected members of a base class are accessible to a derived class only if they are accessed through a derived class pointer/reference.

double Point3D::distance(Point3D pt, Point base) const
{
    int dist_x, dist_y;
    dist_x = base.x_ - x_; // x_ is same as this->x_. Hence it is OK.
                           // base is not a Point3D. Hence base.x_ is not OK.
    dist_y = base.y_ - y_;

    return sqrt(dist_x * dist_x +
                dist_y * dist_y);
}

Allowing access to protected members of a base class through a base class pointer/reference will allow you to change objects in ways that will lead to unintended consequences.

Say you have:

class Base
{
   protected:
     int data;
};

class Derived1 : public Base
{
    void foo(Base& b)
    {
       b.data = 10; // Not OK. If this were OK ... what would happen?
    }
};

class Derived2 : public Base
{
};

int main()
{
    Derived1 d1;
    Derived2 d2;
    d1.foo(d2); 
}

If

       b.data = 10;

were to be allowed in Derived1::foo, you are able to modify the state of d2, an instance of Derived2 by Derived1. That sort of backdoor modification is not a desirable behavior.

like image 132
R Sahu Avatar answered Sep 17 '22 19:09

R Sahu


The public inheritance mode simply means that the object can access protected members of its base class. In this example, every Point3D object can access the x_ and y_ members of Point3D objects only.

However, this does not allow the object to access another Point's protected members from it's base class.

EDIT: As pointed out by J. Lin, simply changing the type of base from Point to Point3D allows the member function to access x_ and y_.

like image 44
Sesh Sadasivam Avatar answered Sep 19 '22 19:09

Sesh Sadasivam