class A
{
protected:
int i;
};
class B: public A
{
public:
void DoAction(A& ra)
{
ra.i = 2;
}
};
void main()
{
}
Компиляю. И получаю:
F:\PRJ\!!! TESTS>cl 1.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
1.cpp
1.cpp(13) : error C2248: 'i' : cannot access protected member declared in class 'A'
1.cpp(5) : see declaration of 'i'
A>class A
A>{
A> protected:
A> int i;
A>};
A>class B: public A
A>{
A> public:
A> void DoAction(A& ra)
A> {
A> ra.i = 2;
A> }
A>};
A>void main()
A>{
A>}
A>
A>Компиляю. И получаю:
A>F:\PRJ\!!! TESTS>cl 1.cpp A>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86 A>Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
A>1.cpp A>1.cpp(13) : error C2248: 'i' : cannot access protected member declared in class 'A' A> 1.cpp(5) : see declaration of 'i'
A>Почему A::i недоступно в потомке?
Переменная A::i в ПОТОМКЕ доступна (в контексте методов класса B). Она недоступна, если потомок (объект класса B) имеет дело с самостоятельным объектом класса A.
A>class A
A>{
A> protected:
A> int i;
A>};
A>class B: public A
A>{
A> public:
A> void DoAction(A& ra)
A> {
A> ra.i = 2;
A> }
A>};
A>void main()
A>{
A>}
A>
A>Компиляю. И получаю:
A>F:\PRJ\!!! TESTS>cl 1.cpp A>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86 A>Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
A>1.cpp A>1.cpp(13) : error C2248: 'i' : cannot access protected member declared in class 'A' A> 1.cpp(5) : see declaration of 'i'
A>Почему A::i недоступно в потомке?
оно доступно, если является подобъектом твоего класса.
Т.е. объекту класса В доступны защищенные члены его собственного подъобекта класса А, но не любые объекты класса А.
Поправочка:
.... g_i>..Она недоступна, если потомок (объект класса B) имеет дело с самостоятельным объектом класса A, пытаясь получить доступ к его экземпляру переменной i.
Дополнение:
>Что характерно, в void DS() такой ошибки нет...
Потому, что в DS идет обращение к собственному экземляру переменной i, доступ к которому разрешен ввиду protected-определения в базовом классе.
Здравствуйте, jazzer, Вы писали:
A>>Почему A::i недоступно в потомке?
J>оно доступно, если является подобъектом твоего класса. J>Т.е. объекту класса В доступны защищенные члены его собственного подъобекта класса А, но не любые объекты класса А.
А можно меня носом в стандарт ткнуть, где это сказано? И как мне поступить в таком случае — что, делать это поле public
Здравствуйте, avgur, Вы писали:
A>А можно меня носом в стандарт ткнуть, где это сказано? И как мне поступить в таком случае — что, делать это поле public
11/1
A member of a class can be
— private; that is, its name can be used only by members and friends of the class in which it is
declared.
— protected; that is, its name can be used only by members and friends of the class in which it is
declared, and by members and friends of classes derived from this class (see 11.5).
— public; that is, its name can be used anywhere without access restriction.
Здравствуйте, avgur, Вы писали:
A>Здравствуйте, jazzer, Вы писали:
A>>>Почему A::i недоступно в потомке?
J>>оно доступно, если является подобъектом твоего класса. J>>Т.е. объекту класса В доступны защищенные члены его собственного подъобекта класса А, но не любые объекты класса А.
A>А можно меня носом в стандарт ткнуть, где это сказано? И как мне поступить в таком случае — что, делать это поле public
ну можно ведь так:
class B;class A
{
protected:
int i;
friend class B;
};
class B: public A
{
public:
void DoAction(A& ra)
{
ra.i = 2;
}
};
void main()
{
}
Здравствуйте, yxiie, Вы писали:
Y>Здравствуйте, avgur, Вы писали:
A>>Здравствуйте, jazzer, Вы писали:
A>>>>Почему A::i недоступно в потомке?
J>>>оно доступно, если является подобъектом твоего класса. J>>>Т.е. объекту класса В доступны защищенные члены его собственного подъобекта класса А, но не любые объекты класса А.
A>>А можно меня носом в стандарт ткнуть, где это сказано? И как мне поступить в таком случае — что, делать это поле public
Y>ну можно ведь так:
Y>
Y>class B;
Y>class A
Y>{
Y> protected:
Y> int i;
Y> friend class B;
Y>};
Y>class B: public A
Y>{
Y> public:
Y> void DoAction(A& ra)
Y> {
Y> ra.i = 2;
Y> }
Y>};
Y>void main()
Y>{
Y>}
Y>
Ну а если у А много наследников? Фрэнд придуман для других вещей, очень редко есть надобность в этих штуках.
В данном случае всегда должна быть функциональность, которая манипулирует содержимым данных, вот к примеру DoAction логичнее определить на уровне класса А:
class A
{
protected:
int i;
public:
void DoAction(A& ra)
{
ra.i = 2;
}
};
если тебе понадобится дополнить функциональность этого метода в наследнике:
class B: public A
{
public:
void DoAction(A& ra)
{
A::DoAction(ra);
blabla;
}
};
Не забывать про виртуальные ф-ции в случае полиморфной функциональности.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Здравствуйте, Batiskaf, Вы писали:
B>Ну а если у А много наследников? Фрэнд придуман для других вещей, очень редко есть надобность в этих штуках. B>В данном случае всегда должна быть функциональность, которая манипулирует содержимым данных, вот к примеру DoAction логичнее определить на уровне класса А:
B> Не забывать про виртуальные ф-ции в случае полиморфной функциональности.
А еще очень странная эта функция DoAction, для того что бы изменить значение поля структуры не обязательно эту структутру передавать в ее же функциональность, можно на самом же экземпляре вызвать метод, в который первым параметром и передастся указатель на экземпляр:
class A
{
protected:
int i;
public:
void DoAction()
{
i = 2;
}
};
void main()
{
A a;
a.DoAction();
}
В твоем же случае нужно передавать один экзкмпляр в метод второго экземпляра, для того что бы тот поменял значение поля первого экземпляра, согласись, странные какие то шаманские пассы, и не создание копированием, и не операция присваивания, черте что
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.