psilogic: (Default)
psilogic ([personal profile] psilogic) wrote2009-07-14 04:31 pm

Западло

[ Предупреждение: для непрограммистов неинтересно ]

Пусть у нас есть два класса - базовый Base и отнаследованный от него Derived. В Derived есть конструктор, похожий на конструктор копии с параметром типа Base.

class Base
{
...
};

class Derived: public Base
{
public:
    Derived() {...}
    Derived(const Base &b) { /* важные манипуляции */ }
};


Допустим, в программе это используется вот так:

Derived d1;
Derived d2(d1);


И оно не работает.

Тщательное расследование показало эпическое западло...



В какой-то момент я внес часть кода в функцию:

void foo(Base &d1)
{
    Derived d2(d1);
    ...
}
...
Derived d1;
foo(d1);



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

Западло состоит в том, что в строке Derived d2(d1) не всегда вызывается второй конструктор и не будут выполняться "важные манипуляции". Вместо этого будет вызван "невидимый" автоматически сгенерированный конструктор-копии, и все поля будут тупо скопированы из d1 в d2.

Это происходит в том случае, если d1 имеет тип Derived. Если Base - то все хорошо. Вот почему та функция исправляла проблему. Так тоже будет работать:

Derived d2((Base&)d1);


Лечится это легко:

class Base
{
...
};

class Derived: public Base
{
public:
    Derived() {...}
    Derived(const Base &b) { /* важные манипуляции */ }
    Derived(const Derived &b) { /* важные манипуляции */ }
};


Но ведь и вляпаться тоже легко...

[identity profile] nefedor.livejournal.com 2009-07-21 02:51 pm (UTC)(link)
Мирослав, в свете нашего давнего знакомства еще на кураевщине, предлагаю на "ты", ладно?

[Вот силами таких текстов и сложилось.]

Что ты предлагаешь мне увидеть из этого предложения, кроме того, что ты сердит на текст и оттого, вероятно, необъективен?

[А какое ваше мнение по поводу функции max, где предлагается сделать параметры ссылками?]

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

[identity profile] psilogic.livejournal.com 2009-07-21 03:04 pm (UTC)(link)
[ Если она будет использоваться для объектов с тяжелым конструктором копирования, то выгоды очевидны. ]

А если будет использоваться для простого типа?

[identity profile] nefedor.livejournal.com 2009-07-21 03:28 pm (UTC)(link)
Тогда, я бы сделал без ссылок. Вопрос только в том, может ли быть заранее известно, что она не будет использоваться только для простых типов? Всегда есть вероятность, что в будущем проект разрастется и будет надстроен монстрами, для которых понадобится max...

[identity profile] psilogic.livejournal.com 2009-07-21 04:15 pm (UTC)(link)
Речь идет о функции, которая на практике используется для простых типов чуть менее, чем всегда. Получается, что чуть менее, чем всегда будет генерироваться неэффективный код.

[identity profile] nefedor.livejournal.com 2009-07-21 04:31 pm (UTC)(link)
Ну вот, как раз мы пришли к теме очередного холивара.
Налицо две полярности - сделать эффективно сейчас для локальной ситуации а если появятся монстры то там и будем думать, или сделать универсально, так что локально оно будет менее эффективно (кстати, а намного ли?), но если придут монстры, то мы к ним будем сразу готовы и глобально выиграем к эффективности.
Я бы не стал говорить о существовании универсального рецепта. Мне кажется, что выбор между этими путями неоднозначен и зависит от характера конкретного проекта. В каких-то случаях можно придерживаться первого метода, в каких-то - второго.

[identity profile] psilogic.livejournal.com 2009-07-21 04:50 pm (UTC)(link)
[ Мне кажется, что выбор между этими путями неоднозначен ]

Вот потому я и не люблю однозначные "советы" :)

[identity profile] nefedor.livejournal.com 2009-07-21 05:25 pm (UTC)(link)
Ты конечно понимаешь, что отвержение однозначных советов есть однозначный совет... :)
Я думаю, мы друг друга поняли.

[identity profile] psilogic.livejournal.com 2009-07-21 05:39 pm (UTC)(link)
Уточню: я не люблю, когда дают однозначные советы по заведомо неоднозначным случаям. :)

[identity profile] nefedor.livejournal.com 2009-07-21 06:08 pm (UTC)(link)
Ну, с этим уже трудно не согласиться.