LINUX.ORG.RU

DMD 2.015 & DMD 1.031

 , ,


0

0

17 июня вышла новая версия экспериментальной ветки компилятора языка D. Большая часть идей для последней версии, по словам Уолтера Брайта, принадлежит Андрею Александреску. Основные изменения:

  • Шаблонные функции теперь могут автоматически определять свой возвращаемый тип.
  • Возможность указывать ограничения для шаблонных параметров.
  • Шаблонные alias параметры теперь могут быть литералами.

И пара десятков багфиксов, которые также были бэкпортированы в DMD 1.031.

>>> Подробный Changelog по версиям со ссылками на скачивание

★★★★★

Проверено: maxcom ()

Ответ на: комментарий от matumba

> Программирование - это вообще, знаете ли, ПРОФЕССИОНАЛЬНАЯ ОБЛАСТЬ

точно профи :)

хотя в целом с этим постом согласен

lester ★★★★
()
Ответ на: комментарий от anonymous

>Ещё один вопрос вдогонку. Зачем добавили ключевое слово finally? У Бьярне Строуструпа в FAQ-е вполне убедительная альтернатива приведена (RAII).

RAII - говно.

Absurd ★★★
()
Ответ на: комментарий от anonymous

>> RAII - говно.

>По-вашему, finally лучше?

Да, лучше. Если конечно не решать несуществующие проблемы типа "забывания" или "error-prone на небрежный код".

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>> RAII - говно.

>>По-вашему, finally лучше?

>Да, лучше. Если конечно не решать несуществующие проблемы типа "забывания" или "error-prone на небрежный код".

А чем, если не секрет? Бьярне говорит, что количество кода при использовании RAII существенно меньше.

anonymous
()
Ответ на: комментарий от anonymous

>> RAII - говно.

> По-вашему, finally лучше?

Одно другого не исключает. Если нужно не просто освободить ресурсы, а выполнить какое-то действие посложнее, нужен finally.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>>>По-вашему, finally лучше?

>>Да, лучше. Если конечно не решать несуществующие проблемы типа "забывания" или "error-prone на небрежный код".

>А чем, если не секрет? Бьярне говорит, что количество кода при использовании RAII существенно меньше.

В фиде ссылались на его приватную переписку с одним из авторов bind, который подумывал о переписывании bind на С++, но хотел чтобы сценарии обработки ошибок были при этом вменяемыми. Бьярне ответил очень аргументированно, написав что они криворукие ламеры и что finally он делать не будет ибо говно. Так какая причина мне утруждаться и приводить какие-то технические доводы?

Absurd ★★★
()
Ответ на: комментарий от lester

>>к примеру С++ обратно совместим с С - т.е. является его продолжением

Это, своего рода, весмьа популярное заблуждение. Первые версии кодогенератора (компилятора тогда не было) действительно были 100% совместимыми. Из плюсового кода генерился сишный, который в последсвии и компилировался. В настоящее время это два совершенно разных языка, с разным синтаксисом и наборами типов данных. Частично расписано на http://ru.wikipedia.org/wiki/C%2B%2B. Отлавливать баги при компиляции сишного кода плюсовым компилятором - то еще удовольствие.

По теме. А есть какие либо реальные проекты, в которых используется D?

anonymous
()
Ответ на: комментарий от Absurd

> Бьярне ответил очень аргументированно, написав что они криворукие ламеры и что finally он делать не будет ибо говно. Так какая причина мне утруждаться и приводить какие-то технические доводы?

Бьярне исправился. Он приводит в своём FAQ-е именно технические аргументы (конкретный пример кода на его официальной странице).

anonymous
()
Ответ на: комментарий от anonymous

>> Бьярне ответил очень аргументированно, написав что они криворукие ламеры и что finally он делать не будет ибо говно. Так какая причина мне утруждаться и приводить какие-то технические доводы?

>Бьярне исправился. Он приводит в своём FAQ-е именно технические аргументы (конкретный пример кода на его официальной странице).

Хелло-Ворлды типа обертки вокруг FILE* меня не интересуют. Да и как он намерен передать такой resource guard клиенту кода во владение? Предлагает делать конструктор копирования, swap() и operator=()?

Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично.

Absurd ★★★
()
Ответ на: комментарий от Absurd

А мне понравился D, оч хотелось бы его практически применить.

Впечатлили шаблоны, вот это мощь. Все то, что делал Александреску с типами все это выражается лаконично и красиво. При чем шаблонный код не выглядит так депрессивно и фриказоидно как в с++. А как вам возможность использования строковых литералов и типов с плавающей точкой как параметров шаблонов? А функции вычисляемые во время компиляции?

Перегрузка функций оставила странное впечатление, мне кажется уступает C++.

Кстати, в последний стандарт с++ вошли вещи которые по началу не планировались. Уж не D ли повлиял? :) Бьярне конечно не сознается

anonymous
()
Ответ на: комментарий от www_linux_org_ru

> НО _1.my_function() не будет функтором, так как . в плюсах не перегружается.

перегрузи не . а ,

anonymous
()
Ответ на: комментарий от anonymous

> А есть какие либо реальные проекты, в которых используется D?

http://www.dsource.org/projects
http://www.dsource.org/projects/tango/wiki/TangoUsers

Короче, пока ничего серьёзного. Хотя http://deadlock.team0xf.com/ очень даже ничего.

PS. Флеймы D vs C++ vs .NET vs Java стали ещё более унылы, чем Win vs Lin...

naryl ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Есть вопрос к любителям языка D. Почему язык оставляет некоторые проблемные возможности и языка Си? Например, сходство между '=' и '==' в сочетании с возможностью ошибочно написать if(a=b), вместо if(a==b) сильно напрягает. Кроме того, возможно тихое падение через switch-case, если случайно забыть break. Ещё удивляет решение сохранить в языке скобки () и {} в управляющих конструкциях. По-моему в Oberon-2 более удобная структура управляющих конструкций. И в Python обошлись без этих скобок. Без скобок легче ориентироваться в тексте программы (точно знаешь, что скобки только в выражениях). Эти решения ещё можно понять в C++ с его попыткой сохранить совместимость, но не в D.

Солидарен со всем, за исключенем оберона.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Absurd

> Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично.

Ссылку пожалуста или пример здесь. Мне интересно.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от anonymous

> перегрузи не . а ,

Это для _конкретных_ экстремалов, не для меня точно.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от naryl

> Флеймы D vs C++ vs .NET vs Java стали ещё более унылы, чем Win vs Lin...

Тут просто школьников мало, и вменяемых много. А размять косточки Д в случае чего я могу.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от anonymous

> Например, сходство между '=' и '==' в сочетании с возможностью ошибочно написать if(a=b), вместо if(a==b) сильно напрягает.

$ cat main.d
import std.stdio;
void main() {
	int a = 1;
	if (a = 2) {
		writefln(a);
	}
}
$ dsss build
[---snip---]
main.d(4): Error: '=' does not give a boolean result
[---snip---]

ЧЯДНТ? :)

> Кроме того, возможно тихое падение через switch-case, если случайно забыть break.

И в Java, и в C#, и в D, дизайнеры признали это полезной фичёй.

Остальное - вопрос вкуса. Всё-равно кто-то будет недоволен.

naryl ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

>> Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично.

>Ссылку пожалуста или пример здесь. Мне интересно.

В конструкторе недоступен this. Следовательно, я не могу там например зарегистрировать обсервер. Деструкторы ввобще бесполезны. Писать много влом, но вот этот автор исследовал С++ независимо от меня, и пришел к тем же выводам: http://yosefk.com/c++fqa/ctors.html http://yosefk.com/c++fqa/dtor.html

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>> Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично.

>>Ссылку пожалуста или пример здесь. Мне интересно.

>В конструкторе недоступен this.

Wow! А это как?

eao197 ★★★★★
()
Ответ на: комментарий от naryl

> Мне интересно было бы услышать речь сторонников C++0x в защиту такой сущности как concept в реализации C++0x. http://www.digitalmars.com/d/2.0/cpp0x.html#concepts

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

>>>> Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично.

>>>Ссылку пожалуста или пример здесь. Мне интересно.

>>В конструкторе недоступен this.

>Wow! А это как?

Кури стандарт. Суперклассы к этому моменту не сконструированы -> объекта не существует -> Такой вещи как this тоже в конструкторе не существует.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>> В конструкторе недоступен this.

>> Wow! А это как?

> Кури стандарт. Суперклассы к этому моменту не сконструированы -> объекта не существует -> Такой вещи как this тоже в конструкторе не существует.

/me медленно выпадает в осадок

tailgunner ★★★★★
()
Ответ на: комментарий от Absurd

>>>>> Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично. 

>>>>Ссылку пожалуста или пример здесь. Мне интересно. 

>>>В конструкторе недоступен this. 

>>Wow! А это как? 

> Кури стандарт. Суперклассы к этому моменту не
> сконструированы -> объекта не существует -> Такой вещи
> как this тоже в конструкторе не существует.

Точно ли нужно курить стандарт C++?
А то у меня что-то такого не наблюдается:

#include <cstdio>

class B {
	public :
		B() {
			std::printf( "B::B(), this is: %p\n", this );
			this->b();
		}

		void b() {
			std::printf( "B::b(), this is: %p\n", this );
		}
};

class C {
	public :
		C() {
			std::printf( "C::C(), this is: %p\n", this );
			this->c();
		}

		void c() {
			std::printf( "C::c(), this is: %p\n", this );
		}
};

class D : public B, public C {
	public :
		D() {
			std::printf( "D::D(), this is: %p\n", this );
			this->b();
			this->c();
			this->d();
		}

		void d() {
			std::printf( "D::d(), this is: %p\n", this );
		}
};

int main() {
	D d;
}

И вывод:

B::B(), this is: 0012FEE3
B::b(), this is: 0012FEE3
C::C(), this is: 0012FEE4
C::c(), this is: 0012FEE4
D::D(), this is: 0012FEE3
B::b(), this is: 0012FEE3
C::c(), this is: 0012FEE4
D::d(), this is: 0012FEE3

eao197 ★★★★★
()
Ответ на: комментарий от tailgunner

>> Кури стандарт. Суперклассы к этому моменту не сконструированы -> объекта не существует -> Такой вещи как this тоже в конструкторе не существует.

> /me медленно выпадает в осадок

ты там не один уже :)

eao197 ★★★★★
()
Ответ на: комментарий от tailgunner

Я думаю, что Absurd иносказательно говорил о том, что виртуальность в конструкторе/деструкторе работает не так, как в других методах.

Legioner ★★★★★
()
Ответ на: комментарий от eao197

>>>>> Инициализацию я обычно делаю в две фазы или более, деинициализацию - аналогично.

>>>>Ссылку пожалуста или пример здесь. Мне интересно.

>>>В конструкторе недоступен this.

>>Wow! А это как?

> Кури стандарт. Суперклассы к этому моменту не сконструированы -> объекта не существует -> Такой вещи как this тоже в конструкторе не существует.

>Точно ли нужно курить стандарт C++? А то у меня что-то такого не наблюдается:

Блин, не заставляй меня ковыряться в этом говне еще раз. Я знаю точно что если надо сделать более-менее нетривиальную инициализацию типа регистрации каких-то обсерверов или листенеров, то ее надо делать в виртуальном методе типа postInit(). В конце концов оказывется что конструкторы никто и не использует ибо они просто мешаются под ногами в силу своей бесполезности, а делают всю работу по инициализации и настройке инстанса в этом самом виртуальном методе postInit(). Аналогично с деструкторами.

Absurd ★★★
()
Ответ на: комментарий от tailgunner

>> Кури стандарт. Суперклассы к этому моменту не сконструированы -> объекта не существует -> Такой вещи как this тоже в конструкторе не существует.

>медленно выпадает в осадок

Ты в прошлый раз выпадал в осадок когда узнал что по стандарту объекты С++ нельзя передавать Си API работающим на уровне чанков памяти.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>> Кури стандарт. Суперклассы к этому моменту не сконструированы -> объекта не существует -> Такой вещи как this тоже в конструкторе не существует.

>>Точно ли нужно курить стандарт C++? А то у меня что-то такого не наблюдается:

>Блин, не заставляй меня ковыряться в этом говне еще раз.

Да надо бы. Чтобы впредь такую ерунду не говорил.

> Я знаю точно что если надо сделать более-менее нетривиальную инициализацию типа регистрации каких-то обсерверов или листенеров, то ее надо делать в виртуальном методе типа postInit(). В конце концов оказывется что конструкторы никто и не использует ибо они просто мешаются под ногами в силу своей бесполезности, а делают всю работу по инициализации и настройке инстанса в этом самом виртуальном методе postInit(). Аналогично с деструкторами.

Классы, которые нуждаются в подобной нетривиальной инициализации/деинициализации, имхо, составляют ничтожный процент от общего числа классов в проекте. Поэтому оценки вроде "конструкторы никто и не использует" противоречат окружающей меня реальности.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

>>Блин, не заставляй меня ковыряться в этом говне еще раз.

>Да надо бы. Чтобы впредь такую ерунду не говорил.

Я уверен что с -Wall оно будет выдавать минимум ворнинг. Пока конструктор не отработает объекта собственно нет. Если this куда-то передали вовне до возникновения "экзепшена в конструкторе" то он станет битым указателем.

>> Я знаю точно что если надо сделать более-менее нетривиальную инициализацию типа регистрации каких-то обсерверов или листенеров, то ее надо делать в виртуальном методе типа postInit(). В конце концов оказывется что конструкторы никто и не использует ибо они просто мешаются под ногами в силу своей бесполезности, а делают всю работу по инициализации и настройке инстанса в этом самом виртуальном методе postInit(). Аналогично с деструкторами.

>Классы, которые нуждаются в подобной нетривиальной инициализации/деинициализации, имхо, составляют ничтожный процент от общего числа классов в проекте. Поэтому оценки вроде "конструкторы никто и не использует" противоречат окружающей меня реальности.

Нет. Классы которым хватало бы конструктора сводятся к cтроуструповым игрушкам типа MyCoolString, MyCoolBigInteger или MyCoolFunctor. Все остальное (99%) требует сложной инициализации.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>Да надо бы. Чтобы впредь такую ерунду не говорил. 

> Я уверен что с -Wall оно будет выдавать минимум ворнинг.
> Пока конструктор не отработает объекта собственно нет.\
> Если this куда-то передали вовне до возникновения "экзепшена в
> конструкторе" то он станет битым указателем.

Почему бы не сделать регистрацию в специальном маленьком
вспомогательном классе:

class registrator_t {
  public :
    registrator_t( some_class_t & what ) : m_what( what ) {
      observer()->register( m_what );
    }
    ~registrator_t() {
      observer()->deregister( m_what );
    }
  private :
    some_class_t & m_what;
};

Которого можно сделать мембером своего класса:

class some_class_t {
  public :
    some_class_t() : m_registrator( *this ) /* Некторые компиляторы
        выдают на такой код предупреждение, но его легко обойти */
    { ... }
    ...
  private :
    registrator_t m_registrator;
    ...
};

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

> Нет. Классы которым хватало бы конструктора сводятся к
> cтроуструповым игрушкам типа MyCoolString, MyCoolBigInteger
> или MyCoolFunctor. Все остальное (99%) требует сложной
> инициализации.

Можешь продемонстрировать это на примере больших и широко доступных
библиотек вроде Qt, ACE или того же Boost-а?

eao197 ★★★★★
()
Ответ на: комментарий от Absurd

> Ты в прошлый раз выпадал в осадок

Да, ты умеешь отжечь.

> когда узнал что по стандарту объекты С++ нельзя передавать Си API работающим на уровне чанков памяти.

Ага, включая memset. Ссылкой на главу стандарта не поделишься?

tailgunner ★★★★★
()
Ответ на: комментарий от eao197

>Почему бы не сделать регистрацию в специальном маленьком вспомогательном классе:

Угу. Предложи еще сделать его еще темплейтом, чтобы это работало для всех сущностей подобного рода. Типичный С++-трюизм: долго ковыряемся в носу чтобы когда-нибудь наконец приступить к написанию логики.

>Некторые компиляторы выдают на такой код предупреждение, но его легко обойти

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

>Можешь продемонстрировать это на примере больших и широко доступных библиотек вроде Qt, ACE или того же Boost-а?

Предпочитаю Си-библиотеки. Меньше гениальности, больше тупого функционала.

Absurd ★★★
()
Ответ на: комментарий от tailgunner

>Ссылкой на главу стандарта не поделишься?

Ищи сам. Первый пример по применению статических политик это всегда какой-нибудь SmartCopy, который в compile-time с помощью трехэтажных шаблонов дедуцирует "а не POD-ы ли мы двигаем?" и если ответ да - то memcpy, иначе - цикл c конструкторами копирования.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>Почему бы не сделать регистрацию в специальном маленьком вспомогательном классе:

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

Можно и шаблоном, но толку от него будет не много, т.к. реализация класса все равно будет завязана на конкретную функцию observer() для получения нужного обсервера.

>Типичный С++-трюизм: долго ковыряемся в носу чтобы когда-нибудь наконец приступить к написанию логики.

Обеспечение exception safety, вообще-то говоря, имеет самое непосредственное отношение к логике программы. И если для этого нужно поковыряться в носу -- значит нужно. Только здесь еще нужно понять, что ковыряться следует в носу, а не в жопе (которая у некоторых к рукам ближе).

>>Некторые компиляторы выдают на такой код предупреждение, но его легко обойти

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

http://eao197.narod.ru/desc/cpp_tricks/this_in_constructor.htm -- это в моем пересказе. Кажется, в Boost есть что-то похожее.

>>Можешь продемонстрировать это на примере больших и широко доступных библиотек вроде Qt, ACE или того же Boost-а?

> Предпочитаю Си-библиотеки. Меньше гениальности, больше тупого функционала.

Мне похеру, что ты предпочитаешь. Ты сказал, что в 99% случаев классы приходится инициализировать через postInit. Ну так докажи свои слова хотя бы на примерах Qt и ACE.

eao197 ★★★★★
()
Ответ на: комментарий от Absurd

> "а не POD-ы ли мы двигаем?" и если ответ да - то memcpy, иначе - цикл c конструкторами копирования.

Всего-то... я тебя разочарую, но и в Си нельзя memcpy копировать, скажем, структуру, в которой есть указатель на malloc'нутый список. То есть копировать можно, но результат тебе не понравится (как и в Си++). Но в Си++ это хоть есть стандартный способ копировать такие объекты - конструктор копирования.

tailgunner ★★★★★
()
Ответ на: комментарий от naryl

>> Кроме того, возможно тихое падение через switch-case, если случайно забыть break.

> И в Java, и в C#, и в D, дизайнеры признали это полезной фичёй.

Для чего полезной? По-моему, только для переманивания программистов с Си и Си++. Но не для новых программистов. И не для тех кто на нескольких языках работает.

anonymous
()
Ответ на: комментарий от eao197

>Обеспечение exception safety, вообще-то говоря, имеет самое непосредственное отношение к логике программы.

С exception safety нет проблем в более других ОО языках нежели в С++.
Можно и в С++ их не иметь если не пользоваться экзепшенями, как это
сделано в Gecko например.

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

>http://eao197.narod.ru/desc/cpp_tricks/this_in_constructor.htm
-- это в моем пересказе. Кажется, в Boost есть что-то похожее.

Да, еще один "трюк". Сколько же их должен знать средний
С++ - программист?

>Ты сказал, что в 99% случаев классы приходится инициализировать
через postInit. Ну так докажи свои слова хотя бы на примерах Qt и ACE.

std::auto_ptr<Widget> createWidget(std::auto_ptr<Foo> foo,
std::auto_ptr<Bar> bar,
std::auto_ptr<Context> some context)
{
std::auto_ptr<Widget> widget(new Widget);
widget->setFoo(foo);
widget->setBar(bar);
widget->attach(some_context);
return widget;
}

Так намного понятнее и разумнее чем танцы с бубном вокруг
конструкторов.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>Ты сказал, что в 99% случаев классы приходится инициализировать 
через postInit.
>> Ну так докажи свои слова хотя бы на примерах Qt и ACE. 

>std::auto_ptr<Widget> createWidget(std::auto_ptr<Foo> foo, 
>std::auto_ptr<Bar> bar, 
>std::auto_ptr<Context> some context) 
>{ 
>std::auto_ptr<Widget> widget(new Widget); 
>widget->setFoo(foo); 
>widget->setBar(bar); 
>widget->attach(some_context); 
>return widget; 
>} 

>Так намного понятнее и разумнее чем танцы с бубном вокруг 
конструкторов.

И? Где здесь postInit и невозможность сделать что-то в
конструкторе Widget?

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

>>> Кроме того, возможно тихое падение через switch-case, если случайно забыть break.

У этого есть свои применения. switch без падения через case всегда легко заменяется на if-else-if.

naryl ★★★★★
() автор топика
Ответ на: комментарий от eao197

>И? Где здесь postInit и невозможность сделать что-то в конструкторе Widget?

В качестве postInit тут выступает attach().

>и невозможность сделать что-то в конструкторе Widget?

А что, мы тут настраиваем инстанс через конструктор?

Absurd ★★★
()
Ответ на: комментарий от Absurd

>>И? Где здесь postInit и невозможность сделать что-то в конструкторе Widget?

>В качестве postInit тут выступает attach().

А, таки attach(). Не setFoo, не setBar, а именно attach -- это в корне меняет дело.

>>и невозможность сделать что-то в конструкторе Widget?

>А что, мы тут настраиваем инстанс через конструктор?

То, что attach() вызывается после setFoo/setBar дает основание думать, что после завершения конструктора объект Widget уже находится в корректном состоянии. Т.е. конструктор Widget свою роль выполнил -- инварианты класса удовлетворены.

Далее из этого примера совершенно не видно, почему Widget не может получать контекст в конструкторе.

Ну и возвращаясь к 99%: объекты Foo, Bar и контекста инициализируются так же через некий postInit()/attach()?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Развели тут оффтопик. :)

http://www.digitalmars.com/d/2.0/class.html#Constructor
Instances of class objects are created with NewExpressions.
The following steps happen:
[snip]
2. The raw data is statically initialized using the values provided in the class definition. The pointer to the vtbl[] (the array of pointers to virtual functions) is assigned. This ensures that constructors are passed fully formed objects for which virtual functions can be called.
[snip]

По-русски: инициализация полей и таблицы виртуальных функций выполняется после вызова аллокатора, но до вызова конструктора. Поэтому из конструктора можно вызывать виртуальные функции.

naryl ★★★★★
() автор топика
Ответ на: комментарий от naryl

> Развели тут оффтопик. :)

Так блин, если люди вроде Absurd-а до D доберуться, то будут поносить его еще больше, чем C++ :)

> По-русски: инициализация полей и таблицы виртуальных функций выполняется после вызова аллокатора, но до вызова конструктора. Поэтому из конструктора можно вызывать виртуальные функции.

Но зато в D конструкторы базового типа нужно вызывать самому. Что черевато:

1) забыванием этого; 2) обращением к методу базового класса до того, как конструктор базового класса отработает и установит корректные значения атрибутов базового класса (значения по умолчанию не всегда являются корректными).

В C++ этого нет.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

>Далее из этого примера совершенно не видно, почему Widget не может получать контекст в конструкторе.

А если он пользуется foo & bar?

>объекты Foo, Bar и контекста инициализируются так же через некий postInit()/attach()?

Контекст - скорее всего долгоживущий объект. Его надо было передавать через что-то с подсчетом ссылок наверно, с auto_ptr я промахнулся. Относительно Foo & Bar: это или структуры с полями или некие интерфейсы с виртуальными функциями. При отсутствии keyed parameters инициализировать десять полей структуры конструктором совершенно уныло. Для интерфейса вообще без разницы как был проинициализирован инстанс который с ним связан. Лучше конечно конструктора с параметрами там не делать чтобы не вынуждать людей которые будут его наследовать чесать репу "а что же нам передать в списке инициализации суперклассу?"

Absurd ★★★
()
Ответ на: комментарий от Absurd

>std::auto_ptr<Widget> createWidget(std::auto_ptr<Foo> foo,

>std::auto_ptr<Bar> bar,

>std::auto_ptr<Context> some context)

Хм, это одному мне кажется, что не стоит передавать auto_ptr по значению?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Хм, это одному мне кажется, что не стоит передавать auto_ptr по значению?

Его надо передавать только по значению. В данном случае это in-параметр, который передается во владение.

Absurd ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.