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] http://technorati.com/people/technorati/ketmar (from livejournal.com) 2009-07-19 06:58 am (UTC)(link)
э… а где западло-то? компилятор сделал точно то, о чём его попросили же. с какой стороны я не смотрел, но равенства «Base» и «Derived» в упор не увидел. более того — не увидел даже фигнюшки для преобразования одного в другое (тогда, емнип, компилер мог бы нашаманить преобразование и вызов конструктора, уж не помню, лень проверять, это идиотизм всё равно). а для случая «коструктор копирования отсутствует» стандарт прямо предписывает его неявно зашаманить, а не ебстись с преобразованием типов. именно поэтому конструктор копирования, если он не очевиден, всегда объявляют явно. а дальше пишут там *this = aValue (при наличии унаследованного — или своего — operator =, натурально).

итого: «а этот пацак всё время думает на языках, продолжения которых не знает!» (ц)

[identity profile] http://technorati.com/people/technorati/ketmar (from livejournal.com) 2009-07-19 07:08 am (UTC)(link)
тьфу, йопт. про преобразование — это ж и есть «второй конструктор», ага. %-)

[identity profile] psilogic.livejournal.com 2009-07-19 08:48 am (UTC)(link)
ну вот и получается, что смотришь и думаешь: конструктор копирования есть, все ништях. никто не забыт, ничто не забыто. а его нет :)

[identity profile] psilogic.livejournal.com 2009-07-19 09:05 am (UTC)(link)
Ну получается время использования языка сопоставимо, так что можешь меня слушать столь же почтительно, как Мейерса :)))

[identity profile] psilogic.livejournal.com 2009-07-19 09:12 am (UTC)(link)
[ Знаю таких "оптимутмистов". ]

А дальше пошел левый пиздёж - наезд, ничем не обоснованный. В таком стиле я разговаривать не буду, времени жалко, пошел нахуй.

[ const std::string c_str("ABC"); ]

Речь шла о числовых константах, у тебя склероз что ле?

[ В современных процессорах необходимые данные на последующую команду загружаются для последующей обработки заранее. ]

Америку, блядь, открыл...

[ Но главное, что компилятор знает, что константа - это одинаковая неизменяемая сущность во многих кусках кода, а define для него - это фигня, разбросанная по всему коду, о сущности которой можно только догадываться ]

Для компилятора нет define, препроцессор уже подставил вместо имени define число. А одно и то же число - это сущность неизменяемая. Короче, не строй из себя идиота.

[identity profile] bsivko.livejournal.com 2009-07-19 10:46 am (UTC)(link)
Опять ругаться начал. Нервы уже не те, да?

>Речь шла о числовых константах, у тебя склероз что ле?

Нет, я работаю с первоисточником. У Мейерса нет ни слова про числовые константы, их похоже выдумал ты.

В любом случае если имеются какие-либо действия по конструированию элемента, они произойдут при использовании define. При const этого нет.

Придумай себе класс числовых значений (например комплексных/рациональных или ещё каких чисел) и получишь соответствующий результат.

>Америку, блядь, открыл...

Для тебя похоже что открыл. Т.к. ты рассуждаешь тут теоретически, а на самом деле во многом все зависит и от компилятора, и от харда. И "в среднем" специалисты говорят, что const позволяет работать быстрее и использовать меньше памяти.

Так что не строй из себя идиота.

Неудобные вопросы ты успешно проигнорил. Недостаток квалификации в предмете и дискуссии "компенсируется" квалификацией в полемике.

>Для компилятора нет define, препроцессор уже подставил вместо имени define число. А одно и то же число - это сущность неизменяемая. Короче, не строй из себя идиота

Это число ещё нужно найти и сопоставить его в различных кусках кода. Может ещё скажешь в каждом "for( int i =0; ..." компилятор где-то 0 хранит как одинаковое число? Фигвам.

[identity profile] bsivko.livejournal.com 2009-07-19 10:48 am (UTC)(link)
Время, но не качество. Может ты хуи в подворотнях пинал сидел на каком-нить проекте в тысячу строк кода, то бишь в болоте, и не знал толком ничего о смежных областях и об изменении всего во времени.

И как писал, мне в данном случае (когда я сам далеко не чайник и даже не любитель в С++) на авторитеты пофиг. Я читаю обоснования, а не правила.

[identity profile] psilogic.livejournal.com 2009-07-19 10:54 am (UTC)(link)
А может наоборот Мейерс хуи пинал, когда книжки не писал :)

[identity profile] psilogic.livejournal.com 2009-07-19 10:58 am (UTC)(link)
[ Нет, я работаю с первоисточником. У Мейерса нет ни слова про числовые константы, их похоже выдумал ты. ]

Я ссылался на первоисточник, на страницы 29-30. Страница 29, читаем:

const double CostEstimate::FudgeFactor = 1.35;

Это не числовая константа?

Мое терпение иссякло. Пошел на хуй. За такое уебство я не баню, но общаться с таким говном вряд ли еще стану.

[identity profile] bsivko.livejournal.com 2009-07-19 11:49 am (UTC)(link)
Это пример, на котором разбирается рекомендация.

Всего хорошего.

P.S.
— Вас не затруднит? Будьте любезны, передайте на билетик, пожалуйста! Спасибо.
— Ну ты, хрен, из интеллигентов, что ли?
— Да нет, что вы, я такое же быдло, как и вы!
(с) Вежливо

[identity profile] psilogic.livejournal.com 2009-07-19 11:52 am (UTC)(link)
Вот поэтому Мейерс и ты с такими рекомендациями стройными рядами идете на хуй

[identity profile] bsivko.livejournal.com 2009-07-19 01:04 pm (UTC)(link)
Мирослав, все хорошо. Мейерса забрали и унесли добрые санитары. Его идеологическая деятельность тебя больше не побеспокоит.

Знал бы такую реакцию, в спор бы не вступал. Здоровье (не только мое) оно того... дороже.

Сейчас ещё раз меня пошлют на всякий случай, и все будет нормально (;

[identity profile] http://technorati.com/people/technorati/ketmar (from livejournal.com) 2009-07-19 01:30 pm (UTC)(link)
не, ну как, как можно подумать, что он есть, если сразу видно, что его нет нифига? O_O

ты ж, вроде бы, не первый год на цпп пишешь, вообще должен «влёт» такое замечать. если уж я, который цпп люто ненавидит и пишет в нём в 90% случаев c-style код, вижу…

это, по-моему, во всех книжках напрочь говорится почти сразу: «если явного конструктора копирования нет, компилятор нашаманит свой. везде и завсегда».

зыж херня это всё. (томно вздыхает) вот шаблоооны… «ах, швецiя!» (ц)

[identity profile] psilogic.livejournal.com 2009-07-19 02:18 pm (UTC)(link)
да это все понятно, просто сочетание всех факторов создает неочевидный глюк. ворнинг тут был бы пользителен.

а про Щаблоны хошь задачку прикольную? :)

[identity profile] http://technorati.com/people/technorati/ketmar (from livejournal.com) 2009-07-19 02:27 pm (UTC)(link)
неа, не хочу. я не умею делать шаблоны, только использовать готовые, у которых хорошая документация. я ж не Ъ-цпп-кодер. я вон до недавних пор не знал, что от шаблонизированного класса можно наследоваться (в смысле, например, от QList<int>).

[identity profile] psilogic.livejournal.com 2009-07-19 02:36 pm (UTC)(link)
ну если захочешь потренироваться то тута:
http://psilogic.livejournal.com/326274.html

[identity profile] nefedor.livejournal.com 2009-07-21 02:44 am (UTC)(link)
Так получилось, что я совсем недавно смотрел упомянутого мейерса, причем не первое издание древнего года, а третье и пока последнее, кажется, 2005го.
Так вот, пару слов.
Во-первых, про enum. Как правильно заметил бсивко, мейерс именно что активно рекомендует использовать enum. Он просто говорит, что в программистских кругах сложилось название для подобного использования enum-а - "enum hack". Но из текста (английского по крайней мере) совершенно никак не следует, что это нечто грязное и нечистоплотное, наоборот, этот "хак" преподносится как нечто, что следует знать и использовать.
Во-вторых, про пункт 3, то есть, про константы - члены класса. Тот же мейерс в той же главе пишет, что для типов int, char и bool объявлять переменную в .cpp не нужно - достаточно декларации в хедере, что является стандартом языка. Правда, некоторые старые компиляторы этого могут не поддерживать, но более-менее новые должны. Поэтому писанины становится меньше в два раза.
Ну и в-третьих, пустые холивары всегда бывают от абсолютизации чего-то. Того же мейерса делать непогрешимым кумиром вряд ли стоит. С другой стороны, также вряд ли стоит утверждать его ламерство, в то время как он является распространенным и уважаемым автором для многих программистских коллективов. Скажем, ты можешь не разделять их и бсивко воззрения на минимизацию времени на отладку и поиск багов, но они в свою очередь, могут не разделить твое видение себя в их рядах в случае поиска работы... :)

[identity profile] psilogic.livejournal.com 2009-07-21 09:21 am (UTC)(link)
[ Он просто говорит, что в программистских кругах сложилось название для подобного использования enum-а - "enum hack". ]

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

[ Правда, некоторые старые компиляторы этого могут не поддерживать, но более-менее новые должны. Поэтому писанины становится меньше в два раза. ]

Здесь вы правы, убедили - поддержка старых компиляторов требуется редко. С сегодняшнего дня начинаю чаще юзать const для констант.

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

[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)
[ Мне кажется, что выбор между этими путями неоднозначен ]

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

Page 3 of 4