C++, просто смешно… 3

Posted by Андрей on Февраль 07, 2008

Что выведет данный код?

#include <stdio.h>

struct A
{
    A(int x = 3) { printf("%d\n", x); }
};

struct B: virtual public A
{
   B() : A(4) {}
}; 


struct C: virtual public A
{
  C() : A(5) { }
}; 

struct D: public B, public C
{

};

int main()
{
    D d;
    B b;
    C c;

    return 0;
}

Ответ:

3
4
5

Что самое смешное, можно из D::D() явно вызвать конструктор A с другим параметром. Наслаждаемся в C++ смесью виртуального наследования, раздельной компиляции и полученной кривости.

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. Stepan Ср, 30 Июл 2008 23:11:33 UTC

    Спасибочки автору. Возможно, в будущем я и действительно реализую аналогичную идею. :)

  2. Большой Чт, 28 Окт 2010 16:18:49 UTC

    Ничего тут кривого нет. Все правильно. Виртуальное наследование подразумевает обязательное вызов конструктора класса A. В Вашем случае это конструктор который принимает параметр int и значение по усмолчанию 3. А конструкторы классов B и С для инициализации класса A не имеет значение, т.к. еще раз повторю иммется виртуальное наследование. и совсем не понимаю причем тут раздельная компиляция. Нельзя нападать на язык полностью не разбираясь в его нюансах

  3. Андрей Пт, 29 Окт 2010 08:13:42 UTC

    Большой, тут необходимо, видимо, учесть, что такое раздельная компиляция. Речь идет о том, что все четыре класса могут быть разнесены в 4 файла. Таким образом, в каждой единице компиляции будет виден свой конструктор. И иного поведения у данной программы и не может быть, но это совершенно неочевидно, когда все в одном файле. Гораздо логичнее было бы считать такую ситуацию ошибкой на этапе компиляции, но опять-таки это невозможно (в силу раздельной компиляции).

Comments