Search code examples
c++inheritancellvm-clang

Accessing protected members in base class objects


Consider:

class A {
protected:
    int _i;
};

class B : public A {
    B(const B & object) {
        _i = object._i;
    };

    B(const A & object) {
        _i = object._i;
    };
};

First copy constructor is correct, because permissions are based on classes, not on objects. So I can reach protected members from my own class objects. Why second constructor (or any similar method) raises compile time error?

In short: Why permission checking in C++ does not regard class inheritance rules in this case?

Also this was encountered in Apple LLVM-4.2 but not in Apple LLVM-4.1.


Solution

  • In short: Why permission checking in C++ does not regard class inheritance rules in this case?

    You're asking for rationale behind the rule which prohibits the second constructor.

    To understand the rationale, consider this code:

    A a;
    a._i = 100; //error, _i is protected 
    

    That is correct, and expected. So far, so good.

    But if the second constructor is allowed (in your code), then anyone can write a class modify as:

    struct modify : public A {
        void i(A & object, int newValue) {
            object._i = newValue; //MODIFY THE PROTECTED MEMBER of the argument!
        };
    };
    

    And then you can do this instead:

    A a;
    modify().i(a, 100); //okay, indirectly modify a._i !!!
    std::cout << a._i << std::endl; //prints 100
    

    If the second constructor can access the protected member of the argument, then modify::i() can also do the same! That way you actually modify the protected members!