Рассматривать:
class A {
protected:
int _i;
};
class B : public A {
B(const B & object) {
_i = object._i;
};
B(const A & object) {
_i = object._i;
};
};
Первый конструктор копирования корректен, поскольку разрешения основаны на классах, а не на объектах. Таким образом, я могу получить доступ к защищенным членам из своих собственных объектов класса.
Почему второй конструктор (или любой подобный метод) вызывает ошибку времени компиляции?
Вкратце: почему проверка разрешений в C ++ не учитывает правила наследования классов в этом случае?
Также это встречалось в Apple LLVM-4.2, но не в Apple LLVM-4.1.
Вкратце: почему проверка разрешений в C ++ не учитывает правила наследования классов в этом случае?
Вы просите обоснование правила, которое запрещает второй конструктор.
Чтобы понять обоснование, рассмотрите этот код:
A a;
a._i = 100; //error, _i is protected
Это правильно и ожидаемо. Все идет нормально.
Но если второй конструктор разрешен (в вашем коде), тогда любой может написать класс modify
как:
struct modify : public A {
void i(A & object, int newValue) {
object._i = newValue; //MODIFY THE PROTECTED MEMBER of the argument!
};
};
И тогда вы можете сделать это вместо:
A a;
modify().i(a, 100); //okay, indirectly modify a._i !!!
std::cout << a._i << std::endl; //prints 100
Если второй конструктор может получить доступ к protected
участник аргумента, то modify::i()
также можно сделать то же самое! Таким образом, вы фактически модифицируете защищенных участников!
Других решений пока нет …