использавание virtual в избранное  новое горячее всё    подписка   модер. 
От: Аноним 306 
Дата: 29.05.08 05:54
Оценка: :))
class B {
public:
      virtual ~B (){}
};

class D : virtual public B {
public:
      void f () {}
};


В каких случаях нужно использовать virtual , и какая разница
между записями следующего вида, если в классе B есть виртуальная функция?
class D : virtual public B
class D : public B

Если в классе B нет виртуальной функции означает ли это
что следующая запись сделает класс B виртуальным?
class D : virtual public B
Re: Это называется виртуальное наследование в избранное  новое    модер. 
От: Erop 
Дата: 29.05.08 06:23
Здравствуйте, Аноним, Вы писали:

А>В каких случаях нужно использовать virtual , и какая разница

Учебник читать не пробовал? Или, хотя бы, поиском тут поискать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: использавание virtual в избранное  новое    модер. 
От: chipmunk 
Дата: 29.05.08 06:50
Здравствуйте, Аноним, Вы писали:

class Base {
public:
  int i;
};

class A : virtual public Base {
};

class B : virtual public Base {
};

class C : public A, public B {
};

int main(int argc, char* argv[]) {
  C c;    
  c.i = 10;  // без virtual будет ругаться, т.к. у класса С будет два члена i - один от A, другой от B
             
  return 0;
}


P.S. в книгах смотреть "ромбовидное наследование"
Re: использавание virtual в избранное  новое    модер. 
От: Кодт модератор 
Дата: 29.05.08 07:00
Здравствуйте, <Аноним>, Вы писали:

<>

Думаю, что на твои вопросы можно найти если не исчерпывающие, то уж по крайней мере объёмные ответы в любой хорошей книге по С++. Начиная со Страуструпа.
Если это, конечно, вопрос новичка.

А если это вопрос человека, внезапно наткнувшегося на странности и неожиданное для себя поведение компилятора и/или программы — то неплохо бы именно об этих странностях поговорить.
К примеру, там иным способом работает RTTI, иной формат указателей на члены, есть нюансы правил доступа к конструкторам (что позволяет запаивать классы от наследования).
Но что именно из этого тебя волнует? Мы же не знаем.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: использавание virtual в избранное  новое    модер. 
От: Аноним 306 
Дата: 29.05.08 07:11
Здравствуйте, chipmunk, Вы писали:
class Base {
public:
  int i;
};

class A : virtual public Base {
};
...


C>P.S. в книгах смотреть "ромбовидное наследование"


Вопрос был в о том в каких случаях используется и не опускается virtual...

Т.е. правильно я понял что если в базовом классе нет виртуальных функций
то чтобы сделать наследование виртуальным нужна запись
class A : virtual public Base
, а если в базовом классе есть виртуальная функция
то получается можно написать короче
class A : public Base
И что при этом разницы действительно никакой нет?
Re[3]: использавание virtual в избранное  новое    модер. 
От: alzt 
Дата: 29.05.08 07:16
Здравствуйте, Аноним, Вы писали:

C>>P.S. в книгах смотреть "ромбовидное наследование"


А>Вопрос был в о том в каких случаях используется и не опускается virtual...


А>Т.е. правильно я понял что если в базовом классе нет виртуальных функций

А>то чтобы сделать наследование виртуальным нужна запись
А>class A : virtual public Base
А>, а если в базовом классе есть виртуальная функция
А>то получается можно написать короче
А>class A : public Base
А>И что при этом разницы действительно никакой нет?

Не правильно.
Лучше смотрите в книгах. Коротко и точно ответить достаточно сложно.
Re[2]: использавание virtual в избранное  новое    модер. 
От: Аноним 306 
Дата: 29.05.08 07:18
Оценка: :)
Здравствуйте, Кодт, Вы писали:


К>А если это вопрос человека, внезапно наткнувшегося на странности и неожиданное для себя поведение компилятора и/или программы — то неплохо бы именно об этих странностях поговорить.

К>К примеру, там иным способом работает RTTI, иной формат указателей на члены, есть нюансы правил доступа к конструкторам (что позволяет запаивать классы от наследования).
К>Но что именно из этого тебя волнует? Мы же не знаем.

Я и спрашиваю что происходит в глубинах класса, почему чаще всего не пишут virtual,
а иногда пишут, это что просто стиль письма или что-то более глубокое. (где читать о глубинах)
Re: использавание virtual в избранное  новое    модер. 
От: sokel 
Дата: 29.05.08 07:31
Кстати, кто-нибудь может привести реальные примеры использования виртуального наследования?
Re: Простое правило в избранное  новое    модер. 
От: Erop 
Дата: 29.05.08 07:38
Оценка:1 (1)
Здравствуйте, Аноним, Вы писали:

А>В каких случаях нужно использовать virtual , и какая разница


Короче. Где и про что читать, тебе сказали.
Вот тебе на работсь:

Простое и ясное правлило.
НЕ ИСПОЛЬЗУЙ virtual в этом месте НИКОГДА!!!


Когда-нибудь изучишь вопрос и поймёшь, что это правило верное в 99,9% случаев...

ЗЫ
IMHO, это кто-то стебётся...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Пример... в избранное  новое    модер. 
От: Erop 
Дата: 29.05.08 07:43
Здравствуйте, sokel, Вы писали:

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


struct IPicture {
    //  ...
};

struct IAnimatedPicture : virtual IPicture {
    //  ...
};

class IPictureImpl : public virtual IPicture {
    //  ...
};

class IAnimatedPictureImpl : public [virtual] IAnimatdPicture, IPictureImpl {
    //  ...
};
"[virtual]" -- читать, как "добавить по желанию"...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Теги: 
Re[2]: использавание virtual в избранное  новое    модер. 
От: Кодт модератор 
Дата: 29.05.08 08:10
Оценка: +1
Здравствуйте, sokel, Вы писали:

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


Я имею этот реальный пример, но привести не могу — уж больно здоровая программа, отрефакторить которую у меня рука не поднимается.

Одно из применений там: классы с интрузивным подсчётом ссылок.
Миксин со счётчиком делается виртуальной базой, в том числе для всех не-COM-интерфейсов (в COM миксин нужно нахлобучивать в каждый финальный класс, поверх кокласса).
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: использавание virtual в избранное  новое    модер. 
От: chipmunk 
Дата: 29.05.08 08:37
Здравствуйте, Аноним, Вы писали:

А>Вопрос был в о том в каких случаях используется и не опускается virtual...


наличие виртуальных методов не имеет никакого отношения к виртуальному наследованию

т.е. наверное можно представить что в данном случае: "class A : virtual public Base" слово virtual применяется не к методам, а к данным класса A
Re: использавание virtual в избранное  новое    модер. 
От: Аноним 199 
Дата: 29.05.08 10:05
Здравствуйте, Аноним, Вы писали:

А>
class B {
А>public:
А>      virtual ~B (){}
А>};

А>class D : virtual public B {
А>public:
А>      void f () {}
А>};
А>


А>В каких случаях нужно использовать virtual , и какая разница

А>между записями следующего вида, если в классе B есть виртуальная функция?
А>class D : virtual public B
А>class D : public B

А>Если в классе B нет виртуальной функции означает ли это

А>что следующая запись сделает класс B виртуальным?
А>class D : virtual public B

Объясняю:
виртуальное наследование имеет смысл только при ромбовидном наследовании.
т.е.
class A;
class B1: A;
class B2: A;
class C: B1, B2;

B1 в себе содержит класс A. B2 в себе содержит класс A.
Класс C содержит в себе B1 и B2. => Класс C содержит в себе два экземпляра класса A.

При виртуальном наследовании такого не происходит, так как экземпляры классов B1 и B2 не включают в себя экземпляр A, а только ссылку на него.
Re[2]: использавание virtual в избранное  новое    модер. 
От: vitalyk 
Дата: 29.05.08 13:01
Оценка:1 (1) :)
Здравствуйте, sokel, Вы писали:

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


Классический пример — std::basic_ostream, std::basic_istream.
... << RSDN@Home 1.2.0 alpha 4 rev. 1052>>
Re[3]: Пример... в избранное  новое    модер. 
От: vitalyk 
Дата: 29.05.08 13:20
Здравствуйте, Erop, Вы писали:

E>
struct IPicture {
E>    //  ...
E>};

E>struct IAnimatedPicture : virtual IPicture {
E>    //  ...
E>};

E>class IPictureImpl : public virtual IPicture {
E>    //  ...
E>};

E>class IAnimatedPictureImpl : public [virtual] IAnimatdPicture, IPictureImpl {
E>    //  ...
E>};
"[virtual]" -- читать, как "добавить по желанию"...


Не нужен там virtual, вот как минимум контр-пример :

#include <iostream>


struct IPicture
{
    virtual void foo() = 0;
};

struct IAnimalPicture : public IPicture
{
    virtual void goo() = 0;
};

struct IAnimatedPicture : public IPicture
{
    virtual void hoo() = 0;
};

class AnimatedAnimalPicture : public IAnimalPicture, public IAnimatedPicture
{
public:
    void foo() { std::cout << "foo" << std::endl; }
    void goo() { std::cout << "goo" << std::endl; }
    void hoo() { std::cout << "hoo" << std::endl; }
};

int main()
{
    AnimatedAnimalPicture pikcha;
    pikcha.foo();
    pikcha.goo();
    pikcha.hoo();
    
    IAnimalPicture * pAnimal = &pikcha;
    pAnimal->foo();
    pAnimal->goo();
    
    IAnimatedPicture * pAnimated = &pikcha;
    pAnimated->foo();
    pAnimated->hoo();
    
    IPicture * pPicture = pAnimated;
    pPicture->foo();
    
    pPicture = pAnimal;
    pPicture->foo();

    return 0;
}


Ни варнингов (VS2005, /W4; Comeau), ни тем более ошибок, и даже работает
... << RSDN@Home 1.2.0 alpha 4 rev. 1052>>
Re[4]: А смысл? в избранное  новое    модер. 
От: Erop 
Дата: 29.05.08 14:11
Здравствуйте, vitalyk, Вы писали:

V>Ни варнингов (VS2005, /W4; Comeau), ни тем более ошибок, и даже работает


А в чём смысл иметь два IPicture, если функции всё равно совпадают?
Вообще какая-то непонятно зачем нужная иерархия.

То что я привёл, имел целью сделать так, чтобы реализация IAnimatedPictureImpl смогла унаследовать релизацию IPicture из IPictureImpl.

А у тебя вся реализация сидит в AnimatedAnimalPicture... А если тебе надо и просто IPicture реализовать, неанимированную?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: А смысл? в избранное  новое    модер. 
От: vitalyk 
Дата: 29.05.08 14:25
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>То что я привёл, имел целью сделать так, чтобы реализация IAnimatedPictureImpl смогла унаследовать релизацию IPicture из IPictureImpl.


Да, прошу прощения, не обратил внимания, что это у Вас IPictureImpl, принял его за просто еще один IPicture-производный интерфейс .

П.С. ...должно быть какое-то наказание за использование префикса "I" в названиях неинтерфейсных классов...
... << RSDN@Home 1.2.0 alpha 4 rev. 1052>>
Re[6]: А смысл? в избранное  новое    модер. 
От: Erop 
Дата: 29.05.08 14:37
Здравствуйте, vitalyk, Вы писали:

V>П.С. ...должно быть какое-то наказание за использование префикса "I" в названиях неинтерфейсных классов...

Почему? XxxImpl реализация Xxx -- не менее логичная нотация, чем любая другая

Но я, конечно, мог бы и понятнее написать, наверное
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: использавание virtual в избранное  новое    модер. 
От: Кодт модератор 
Дата: 29.05.08 14:59
Здравствуйте, Кодт, Вы писали:

К>Одно из применений там: классы с интрузивным подсчётом ссылок.

К>Миксин со счётчиком делается виртуальной базой, в том числе для всех не-COM-интерфейсов (в COM миксин нужно нахлобучивать в каждый финальный класс, поверх кокласса).

Да, кстати.
По сути, виртуальная база нахлобучивается на каждый финальный класс. Только это делает компилятор, а не программист ручками.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!