C++, наследование и операторы

Slavaga

Че-то я туплю...
class X
{
...
};
class Y1 : public X
{
...
};
class Y2 : private X
{
...
};
дальше:
X * x;
Y1 * y1;
Y2 * y2;
x = y1; //работает
x = y2; //не работает - cannot convert bla-bla-bla
Я так понимаю в Y2, надо перегрузить какой-то оператор. Какой? Оператор приведения типа или оператор = ? И как? Че-то ниче не получается =\

kokoc88

cannot convert bla-bla-bla

Чтобы знающие люди могли ответить, не имея под рукой компилятора и не эмулируя твою ситуацию, надо писать текст ошибки полностью.

trobak

Из общих соображений, ясно, чего не нравится компилятору - X является private предком для y2, а посему пользователю y2 нельзя давать доступ к скрытому X.
Так что вопрос, а правильно ли тут спроектированы классы, если хочется получать доступ к тому, что вообще-то в private сидит?
Ну а если все же очень нужно, то попробуй в Y2 определить оператор, который X возвращает.

psihodog

причём тут перегрузка операторов?
у тебя действие над указателями выполняется, а не над объектами.
gcc совершенно логично ругается:
a.cc:21: error: `X' is an inaccessible base of `Y2'

klyv

по-моему, надо объявить дружественный для Х оператор =.

Slavaga

Чтобы знающие люди могли ответить, не имея под рукой компилятора и не эмулируя твою ситуацию, надо писать текст ошибки полностью.
cannot convert Y2* to X*

Slavaga

Да мне не надо доступ к данным получать. Мне надо автоматическое приведение типа делать, чтобы не писать Y * y = (Y*)x2.
Можно, конечно public'ом оставить, но тогда станут доступны методы, которыми я никогда напрямую не буду пользоваться.
попробуй в Y2 определить оператор, который X возвращает.
Не получается =)

mira-bella


class X
{
...
};
class Y1 : public X
{
...
};
class Y2 : private X
{
...
};
дальше:
X * x;
Y1 * y1;
Y2 * y2;
x = y1; //работает
x = y2; //не работает - cannot convert bla-bla-bla

если очень не хочется объявлять public вместо private, то сделай функцию, в которой происходит присвоение friend-ом класса Y2.

psihodog

а вообще тут подойдет и перегрузка оператора конверсии и перегрузка оператора присвоения (если правильно делать, конечно но это все извращение, имхо.
пример в студию, плиз.

Olyalyau

Можно, конечно public'ом оставить, но тогда станут доступны методы, которыми я никогда напрямую не буду пользоваться.
Допустим тебе удалось сделать x=y2;
Теперь тебе доступны (private) методы объекта (* y2) унаследованные от X простым x->...
Объясни пожалуйста, какой смысл в этом случае от приватности наследования?

mira-bella

+1

mira-bella

Вообще я ошибся (показалось, что там объекты, а не указатели).
Перегрузить присвоение указателей точно нельзя (а присвоение объектов можно перегрузить).
Может перегрузить конверсию ссылок и можно, но имхо не получится. Если невозможно, то и слава богу - ибо нефиг.

Slavaga

Мне нужно вызывать библиотечные функции (билдеровские, vcl которые требуют в качестве входного параметра указатели на объекты TObject (в нашем случае X). Мои объекты (Y1 или Y2) есть наследники от TObject исключительно для совместимости. Таким образом, у меня есть два варианта работы: либо использую объекты в стиле Y2 и вручную делаю конверсию типов везде, где это необходимо, либо использую объекты в стиле Y1 и получаю в наследство от TObject полтора десятка методов, использующихся в системных целях.
Объясни пожалуйста, какой смысл в этом случае от приватности наследования?
Хотел спрятать ненужные мне методы. Видимо, пока придется остановиться на втором варианте.

Slavaga

присвоение объектов можно перегрузить
С объектами-то понятно, я думал, конверсию ссылок тоже можно перегрузить.

mira-bella

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

Olyalyau

В C++ защита членов и методов от попытки использовать их не так как положено носит довольно примитивный характер. С точки зрения языка всё просто: можешь в результате некоторой операции получить доступ, который не предусматривался создателем класса -- значит надо объявить эту операцию незаконной и ругаться на неё. Но и твоя ситуация просто объясняется: ты предоставляешь сторонней библиотеке доступ к унаследованным методам класса. Другими словами, ты позволяешь ей обращаться напрямую к методам, которые защищены приватным наследованием. Это некорректно. Предполагается, что раз создатель класса-потомка сделал наследование приватным, значит всю работу со своим предком он выполняет сам в соответствии с одному ему известными инвариантами. Это тоже самое, что и приватные члены -- но только приватные предки. Тому, кто заявил, что наследование приватное, язык гарантирует что, законными средствами никто другой в обход него к предку доступа не получит. В твоём случае получает -- ну так ты обязан объявить наследование открытым.
Оставить комментарий
Имя или ник:
Комментарий: