Открыть дедушку
От: Were  
Дата: 13.01.09 16:26
Оценка:
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 не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.
Заранее спасибо.
Re: Открыть дедушку
От: Ovl Россия  
Дата: 13.01.09 16:31
Оценка:
а если добавить virtual I?

class B : protected A, virtual I
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re: Открыть дедушку
От: Vain Россия google.ru
Дата: 13.01.09 16:36
Оценка:
Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: Открыть дедушку
От: Were  
Дата: 13.01.09 16:41
Оценка:
Здравствуйте, Ovl, Вы писали:

Ovl>а если добавить virtual I?


Ovl>
Ovl>class B : protected A, virtual I
Ovl>


Конкретно так не заработает, хотя заработает вот так:
class A : virtual public I
{
};
class B : protected A, virtual public I
{
};


Но иметь виртуальные базы ради таких глупостей совсем не хочется.
Re[2]: Открыть дедушку
От: Were  
Дата: 13.01.09 16:43
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, Were, Вы писали:


W>>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.

V>Обычным С-кастом, но в "ссылочном" виде:
V>
V>I& ri = (I&)b;
V>


Лучше тогда reinterpret_cast'ом, но вопрос насколько это безопасно и не UB-ли это вообще?
Re[3]: Открыть дедушку
От: Erop Россия  
Дата: 13.01.09 17:48
Оценка:
Здравствуйте, Were, Вы писали:

W>Лучше тогда reinterpret_cast'ом, но вопрос насколько это безопасно и не UB-ли это вообще?


Ясный пень, что UB...

А зачем это надо?
Очень может быть, что можно сделать всё шиворот -навыворот, например:
template<typename A> class I : protected A { ... };
class A { ... /* I<A> тут уже доступен! */ };
class B : public I<A> { ... };
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Открыть дедушку
От: Were  
Дата: 13.01.09 17:56
Оценка:
Здравствуйте, 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 — это интерфейс, так что темплейтный вариант не прокатит.
Re[5]: Открыть дедушку
От: Erop Россия  
Дата: 13.01.09 19:39
Оценка:
W>I — это интерфейс, так что темплейтный вариант не прокатит.
Если это интерфейс, то чем плох явный метод его получения?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Открыть дедушку
От: Were  
Дата: 13.01.09 20:07
Оценка:
Здравствуйте, Erop, Вы писали:

W>>I — это интерфейс, так что темплейтный вариант не прокатит.

E>Если это интерфейс, то чем плох явный метод его получения?
В смысле метод — член класса? Ну это некая избыточность, если не найдутся другие решения, я лучше все в A объявлю protected, а унаследую его в public.
Re: Открыть дедушку
От: rg45 СССР  
Дата: 13.01.09 20:28
Оценка:
Здравствуйте, 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;
};

?
--
Справедливость выше закона. А человечность выше справедливости.
Re: Открыть дедушку
От: cencio Украина http://ua-coder.blogspot.com
Дата: 13.01.09 20:56
Оценка: 6 (1) +2
Здравствуйте, 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;
}
Re[2]: Открыть дедушку
От: Were  
Дата: 13.01.09 21:23
Оценка:
Здравствуйте, cencio, Вы писали:

C>Здравствуйте, Were, Вы писали:


W>>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.


C>это безсмысленный вопрос. нужно менять дизайн, а то похоже на удаление гланд через задний проход.

C>Обьявляя:

C>
C>class B : protected A
C>


C>програмист как раз и пробудет предотвратить средствами языка подобные преобразования. Поскольку А — протектед базовый клас к нему доступ могут получить только члены класа и friends.

C>надо или убирать protected или менять описание на

Тем не менее, есть директива using, которая позволяет открыть отдельные члены базового класса.
Re: Открыть дедушку
От: Alexander G Украина  
Дата: 13.01.09 21:42
Оценка: +2
Здравствуйте, Were, Вы писали:

W>class B : protected A


Ух ты. А что такое protected наследование и зачем оно нужно?
Русский военный корабль идёт ко дну!
Re[3]: Открыть дедушку
От: cencio Украина http://ua-coder.blogspot.com
Дата: 13.01.09 22:37
Оценка: -1
Здравствуйте, 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 просто вводит более короткий синтаксис, а правила доступа не изменяет.
Re[2]: Открыть дедушку
От: Dair Россия  
Дата: 13.01.09 23:06
Оценка:
AG>Ух ты. А что такое protected наследование и зачем оно нужно?



При таком наследовании все методы класса-родителя являются protected.

Зачем такое на практике — прямо так трудно придумать пример, я использовал раза полтора, но в множественном наследовании:


class Derived: public MainParent, protected SomethingElse {};
Re[3]: Открыть дедушку
От: Alexander G Украина  
Дата: 13.01.09 23:19
Оценка:
Здравствуйте, 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 наследования.


Защищенное наследование применяется в паттерне "шаблонный метод".
Re: Открыть дедушку
От: vac_  
Дата: 13.01.09 23:53
Оценка:
Здравствуйте, Were, Вы писали:

W>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход.

W>Заранее спасибо.

Используйте идиому pimpl.
Re[4]: Открыть дедушку
От: Were  
Дата: 14.01.09 00:13
Оценка:
Здравствуйте, cencio, Вы писали:

W>>Тем не менее, есть директива using, которая позволяет открыть отдельные члены базового класса.


C>в смысле открыть члены базового класса? какой синтаксис имеете в виду?

C>директива using просто вводит более короткий синтаксис, а правила доступа не изменяет.

Синтаксис обычный:
class A
{
public:
    void Method() const {}
};

class B : protected A
{
public:
    using A::Method;
};

B().Method(); // OK
Re[5]: Открыть дедушку
От: Alexander G Украина  
Дата: 14.01.09 06:43
Оценка:
Здравствуйте, Аноним, Вы писали:

AG>>Приведи таки пример использования protected наследования.


А>Защищенное наследование применяется в паттерне "шаблонный метод".


Покажите такую реализацию. И объясните, почему там нужно не public или private, а именно protected наследование. Насколько я понимаю, перекрываемые виртуальные методы private или protected, сам шаблонный метод public, м наследование открытое — возможно, я всё делаю неправильно.

В книге GoF необычные виды наследования не используются.
Русский военный корабль идёт ко дну!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.