Коротке питання по ООП в C++

У 3-ому російському виданні «Бьерн Страуструп. Язык программирования C++. Специальное издание» у главі В.11.2 на ст.928 є такий код (наводжу тільки ті рядки, які стосуються справи):

class X {
public:
    int a;
    //...
};

class Y2: protected X {};

class Z2: public Y2 {void f(Y2*);};

void Z2::f(Y2* py2) {
    X* px;
    px = py2;   // ошибка: X - защищенный базовый класс для Y2,
                // а Z2 - производной класс от Y2, но нам не известно,
                // что py2 принадлежит к Z2 или
                // как Y2::X используется в обьектах, не принадлежащих к Z2
    py2->a = 7; // ошибка: Z2 не знает, как Y2::a используется в обьектах,
                // не принадлежащих к Z2
}

На інструкції py2-> a = 7; мій компілятор (GNU GCC Compiler), як і очікувалось, видає помилку. А на px = py2; — чомусь ні. 0_o Як ви можете це пояснити? Наперед дякую.: -)

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Да.)

Кстати, вот эта специфика:

Спецификатор доступа к базовому классу управляет доступом к членам базового класса и преобразованием указателей и ссылок из типа производного класса в тип базового класса. Рассмотрим класс D, производной от базового класса B:
•Если B является закрытым базовым классом, его открытые и защищенные члены могут быть использованы только функциями-членами и друзьями D. Только друзья и члены D могут преобразовать D* в B*.
•Если B является защищенным базовым классом, его открытые и защищенные члены могут быть использованы только функциями-членами и друзьями D и его производных классов. Только друзья и члены D и его производных классов могут преобразовать D* в B*.

•Если B является открытым базовым классом, его открытые члены могут быть использованы любой функцией. Кроме того, его защищенные члены могут быть использованы членами и друзьями D и его производных. Любая функция может преобразовать D* в B*.

«Бьерн Страуструп. Язык программирования C++. Специальное издание», 15.3.2, стр. 460.


В данном случае все нормально работать должно, здесь идет преобразование типов

Есть специфика, если наследование не public. Собственно, об этом весь топик)

void Z2: f (Y2* py2) {
X* px;
px = py2; ...}
В данном случае все нормально работать должно, здесь идет преобразование типов

указатель на Y2 преобразуется к указателю на базовый тип X. Преобразование должно отработать и никаких ошибок.

я правильно понял, что обьект какого-то класса может в своем методе приводить указатели на совсем другие обьекты того же класса к указателям типа их protected-родительского класса?

Да, верно! И с Сергеем согласен — по возможности, практиковаться в языке — святое дело!:)

Денис и s, я правильно понял, что обьект какого-то класса может в своем методе приводить указатели на совсем другие обьекты того же класса к указателям типа их protected-родительского класса?

Согласен, что лучше читать/смотреть на мове оригинала. Пришлось читать русскую версую, так как нужно было максимально быстро разобраться (английский понимаю медленнее, чем русский).; -)

Хотя нет, все, что я выше написал, было в старом издании, потом этот пример изменили, значит в переводе вроде нормально все.
www.research.att.com/...printing15.html

pg 851 replace the first example by

	void Z2::f(Y1* py1, Y2* py2, Y3* py3)
	{
		X* px = py1;	// ok: X is a public base class of Y1
		py1->a = 7;	// ok
		px = this;		// ok: X is a protected base of Y2, and Z2 is derived from Y2
		a = 7;		// ok
		px = py2;		// error: X is a protected base of Y2, and Z2 is derived from Y2,
					// but we don't know that py2 is a Z2 or how Y2::X is used in a non-Z2 object
		py2->a = 7;	// error: Z2 doesn't know how Y2::a is used in a non-Z2 object
		px = py3;		// error: X is a private base of Y3
		py3->a = 7;	// error
	}

Это переводчики нахимичили (перепутали код со следующим примером, где X — private). Комментарии вообще непонятно откуда такие взялись...

В гугле по автору и названию сразу находится английский вариант книжки, где на странице 851 видим:

void Z2::f(Y1* py1, Y2* py2, Y3* py3)
{
       X* px = py1;   // ok: X is a public base class of Y1
       py1->a = 7;    // ok

px = py2;       // ok: X is a protected base of Y2, and Z2 is derived from Y2
       py2->a = 7;    // ok

px = py3;       // error: X is a private base of Y3
       py3->a = 7;    // error
}

Но там при py2-> a = 7 нет ошибки, надо разобраться…
Вообще, советую, по возможности, читать книги, смотреть фильмы и т.д. на языке оригинала, т.к. перевод сейчас в большинстве случаев плохой и искажающий смысл.

Есть исключения, но их очень мало.

py2-> a = 7; //ошибка записи в protected member, для класса y2 мембер a теперь protected

px = py2; // тут приведение к базовому типу, никаких ошибок нет

А на px = py2; — чомусь ні. 0_o Як ви можете це пояснити? Наперед дякую.: -)

Моё мнение.
Этот фрагмент кода используется в функции, которая имеет доступ к protected объектам, включая this, посему всё корректно.

Если заменить

class Y2: protected X {};

на

class Y2: private X {};

- ошибка должна быть, или просто использовать фрагмент

X* px;
Y2* py2 = new Y2;
px = py2;

в постороннем классе или в main.

Комментировать комментарии не берусь:)

Так ж у джаві нема вказівників. Чи ти маєш на увазі спробувати присвоєння об’єктів?

Стосовно каментів, то, дійсно, вони трохи дивні.

спробуй подивитись на джаву

це не жарт

Підписатись на коментарі