J. Lin
J. Lin

Reputation: 269

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?

Upvotes: 9

Views: 294

Answers (2)

Sesh Sadasivam
Sesh Sadasivam

Reputation: 39

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_.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206567

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.

Upvotes: 6

Related Questions