class I
{
};
class A : public I
{
};
class B : protected A
{
};
B b;
I& ri = b; // error C2243: 'type cast' : conversion from 'B *__w64 ' to 'I &' exists, but is inaccessible
Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
Заранее спасибо.
Здравствуйте, Were, Вы писали:
W>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
Обычным С-кастом, но в "ссылочном" виде:
I& ri = (I&)b;
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, Were, Вы писали:
W>>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход. V>Обычным С-кастом, но в "ссылочном" виде: V>
V>I& ri = (I&)b;
V>
Лучше тогда reinterpret_cast'ом, но вопрос насколько это безопасно и не UB-ли это вообще?
Здравствуйте, Were, Вы писали:
W>Лучше тогда reinterpret_cast'ом, но вопрос насколько это безопасно и не UB-ли это вообще?
Ясный пень, что UB...
А зачем это надо?
Очень может быть, что можно сделать всё шиворот -навыворот, например:
template<typename A> class I : protected A { ... };
class A { ... /* I<A> тут уже доступен! */ };
class B : public I<A> { ... };
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Were, Вы писали:
W>>Лучше тогда reinterpret_cast'ом, но вопрос насколько это безопасно и не UB-ли это вообще?
E>Ясный пень, что UB...
E>А зачем это надо? E>Очень может быть, что можно сделать всё шиворот -навыворот, например:
template<typename A> class I : protected A { ... };
E>class A { ... /* I<A> тут уже доступен! */ };
E>class B : public I<A> { ... };
I — это интерфейс, так что темплейтный вариант не прокатит.
W>I — это интерфейс, так что темплейтный вариант не прокатит.
Если это интерфейс, то чем плох явный метод его получения?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
W>>I — это интерфейс, так что темплейтный вариант не прокатит. E>Если это интерфейс, то чем плох явный метод его получения?
В смысле метод — член класса? Ну это некая избыточность, если не найдутся другие решения, я лучше все в A объявлю protected, а унаследую его в public.
Здравствуйте, Were, Вы писали:
W>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
Возникают сомнения по поводу наследования B от A. Не лучше ли его заменить агрегированием:
class I
{
public:
virtual void foo() = 0;
};
class A : public I
{
public:
virtual void foo();
};
class B : public I
{
public:
virtual void foo() {a.foo();}
protected:
A a;
};
?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Were, Вы писали:
W>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
это безсмысленный вопрос. нужно менять дизайн, а то похоже на удаление гланд через задний проход.
Обьявляя:
class B : protected A
програмист как раз и пробудет предотвратить средствами языка подобные преобразования. Поскольку А — протектед базовый клас к нему доступ могут получить только члены класа и friends.
надо или убирать protected или менять описание на
class I
{
};
class A : public I
{
};
class B : protected A
{
friend void DoNothing();
};
void DoNothing()
{
B b;
I& ri = b;
}
Здравствуйте, cencio, Вы писали:
C>Здравствуйте, Were, Вы писали:
W>>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
C>это безсмысленный вопрос. нужно менять дизайн, а то похоже на удаление гланд через задний проход. C>Обьявляя:
C>
C>class B : protected A
C>
C>програмист как раз и пробудет предотвратить средствами языка подобные преобразования. Поскольку А — протектед базовый клас к нему доступ могут получить только члены класа и friends. C>надо или убирать protected или менять описание на
Тем не менее, есть директива using, которая позволяет открыть отдельные члены базового класса.
Здравствуйте, Were, Вы писали:
W>Здравствуйте, cencio, Вы писали:
C>>Здравствуйте, Were, Вы писали:
W>>>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
C>>это безсмысленный вопрос. нужно менять дизайн, а то похоже на удаление гланд через задний проход. C>>Обьявляя:
C>>
C>>class B : protected A
C>>
C>>програмист как раз и пробудет предотвратить средствами языка подобные преобразования. Поскольку А — протектед базовый клас к нему доступ могут получить только члены класа и friends. C>>надо или убирать protected или менять описание на
W>Тем не менее, есть директива using, которая позволяет открыть отдельные члены базового класса.
в смысле открыть члены базового класса? какой синтаксис имеете в виду?
вот небольшая цитата из мсдн
using Declaration
...
All instances of a name mentioned in a using declaration must be accessible. In particular, if a derived class uses a using declaration to access a member of a base class, the member name must be accessible. If the name is that of an overloaded member function, then all
директива using просто вводит более короткий синтаксис, а правила доступа не изменяет.
Здравствуйте, Dair, Вы писали:
D>Зачем такое на практике — прямо так трудно придумать пример, я использовал раза полтора, но в множественном наследовании:
D>
D>class Derived: public MainParent, protected SomethingElse {};
D>
И дальше что, какой смысл именно protected наследования ?
Если речь о доминировании (MainParent и SomethingElse имеют общую виртуальную базу и виртуальные методы перекрыты в SomethingElse) — достаточно приватного наследования.
protected-ность наследования может проявиться только в случае дальнейшего наследования от Derived, иначе protected наследование ведёт себя как private наследование.
Приведи таки пример использования protected наследования.
Русский военный корабль идёт ко дну!
Re[4]: Открыть дедушку
От:
Аноним
Дата:
13.01.09 23:49
Оценка:
Здравствуйте, Alexander G, Вы писали:
AG>Приведи таки пример использования protected наследования.
Защищенное наследование применяется в паттерне "шаблонный метод".
Здравствуйте, Were, Вы писали:
W>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход. W>Заранее спасибо.
Здравствуйте, cencio, Вы писали:
W>>Тем не менее, есть директива using, которая позволяет открыть отдельные члены базового класса.
C>в смысле открыть члены базового класса? какой синтаксис имеете в виду? C>директива using просто вводит более короткий синтаксис, а правила доступа не изменяет.
Синтаксис обычный:
class A
{
public:
void Method() const {}
};
class B : protected A
{
public:
using A::Method;
};
B().Method(); // OK
Здравствуйте, Аноним, Вы писали:
AG>>Приведи таки пример использования protected наследования.
А>Защищенное наследование применяется в паттерне "шаблонный метод".
Покажите такую реализацию. И объясните, почему там нужно не public или private, а именно protected наследование. Насколько я понимаю, перекрываемые виртуальные методы private или protected, сам шаблонный метод public, м наследование открытое — возможно, я всё делаю неправильно.
В книге GoF необычные виды наследования не используются.