2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Ищу хороший справочник по C++
Сообщение01.04.2012, 21:21 
Причем хотелось бы, чтобы он был "концентрированный", с кучей перекрестных ссылок. И подробный чтоб! Например, если рассказывает про слово return, так чтобы там было написано, как именно возвращаемое значение будет возвращаться, какие там конструкторы или операторы неявно вызываться будут и т.п.

Такой справочник, чтобы из него легко было узнать, что строчка MyClass myObj = anotherMyObj; будет приводить к вызову конструктора копирования, а строчка myObj = anotherMyObj; — к вызову оператора присваивания. Такой справочник, в котором будет разъяснено, почему MyClass::MyClass(const AnotherClass& t): m_t(t) {} работает, а MyClass::MyClass(const AnotherClass& t) { m_t = t; } может приводить к аварийному завершению программы.

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение02.04.2012, 10:00 
Стандарт смотрели? Думаю, что смотрели. Но так, на всякий случай: C++ Standard - ANSI ISO IEC 14882, Second edition 2003-10-15.pdf и 14882:2011.
Все здесь.

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение02.04.2012, 16:33 
Да, у меня есть копия стандарта. Но он настолько нудный, что...

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение02.04.2012, 17:08 
Аватара пользователя
Такой книги пока не написано (есть такие, которые содержат эту информацию, но в другом порядке изложенную). Напишите вы!

Стандарт (и книги типа Страуструпа) могут помочь вам составить план изложения, и ничего не упустить.

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 21:50 
Munin в сообщении #554870 писал(а):
(есть такие, которые содержат эту информацию, но в другом порядке изложенную)

Может, дадите парочку наименований? А то сегодня как лбом об стену влетел в проблему с конструкторами. Оказывается, при создании объекта сначала вызываются конструкторы базовых классов, сверху вниз, потом конструкторы для полей, которые сами объекты, и лишь потом собственно сам конструктор класса — и это невозможно изменить.

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

(Оффтоп)

И еще некоторые сишники поплевывают на Delphi, мол, там всякие ограничения и полезные вещи отсутствуют... может быть, зато там я сам могу решать, когда мне вызывать конструкторы базовых классов и вызывать ли их вообще — при создании объекта сразу вызывается конструктор класса, и программист в нем получает на вход полностью неинициализированный объект. Свобода!

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 22:15 
Читали Саттера, Майерса?
    Герб Саттер. Решение сложных задач на С++.
    Скотт Майерс. Эффективное использование С++.
У них несколько книг с похожими названиями.

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 22:46 
Joker_vD в сообщении #556317 писал(а):
когда мне вызывать конструкторы базовых классов и вызывать ли их вообще
Простой порядок "конструирования" полей совпадает с порядком их объявления в классе (а не с порядком конструкторов в списке инициализации). Порядок вызова конструкторов базовых классов при множественном наследовании совпадает с порядком этих классов в списке наследования. Если же требуется наличие какой-либо более сложной логики вызова конструкторов, необходимо убедиться, что для всех нужных полей есть конструкторы по умолчанию, и реализовывать эту логику собственно в теле конструктора данного класса. Все очень просто и гибко.
Фраза же по поводу "вызывать ли их вообще" кажется мне весьма опасной. Лично я не могу себе представить, в каком случае может не понадобиться вызов хоть какого-нибудь конструктора...

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 23:33 
EtCetera в сообщении #556340 писал(а):
Если же требуется наличие какой-либо более сложной логики вызова конструкторов, необходимо убедиться, что для всех нужных полей есть конструкторы по умолчанию, и реализовывать эту логику собственно в теле конструктора данного класса. Все очень просто и гибко.

А если его нету, этого конструктора по умолчанию? Давайте я продемонстрирую:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
class DataClass {
public:
  DataClass(const DataClass& o);
  DataClass(vec_ZZ_pE data);
};

class MainClass{
private:
  int a, p, u;
  DataClass data;
public:
  MainClass(int _a) {
    ifstream F(filesTable[a]);
    a = _a;
    F >> p >> u;
    InitZZ(p, u);
    vec_ZZ_pE t(INIT_SIZE, ZZ_pE::cardinality() * 20);
    F >> t;
    data = DataClass(t);
    F.close();
  }
};


Любые конструкторы класса vec_ZZ_pE должны вызываться лишь ПОСЛЕ вызова InitZZ, иначе хана. Объект DataClass по смыслу своему не может быть пустышкой — он внутри состоит не из полей типа ZZ_pE*, а из полей ZZ_pE, т.е. все равно, как ни крути, нужно сначала вызвать InitZZ. Я выкрутился, но настроение испортилось.

EtCetera в сообщении #556340 писал(а):
Лично я не могу себе представить, в каком случае может не понадобиться вызов хоть какого-нибудь конструктора...

Сейчас и я не могу, но поищу и скажу. По крайней мере, возможность вызывать конструкторы полей и конструкторы базового класса в нужный тебе момент инициализации — весьма удобна.

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 23:58 
Аватара пользователя
Joker_vD в сообщении #556317 писал(а):
Может, дадите парочку наименований?

gribble911 в сообщении #556324 писал(а):
Читали Саттера, Майерса?

Ещё Александреску, Джосаттис, Вандевурд.

И ещё есть одна старая, не переиздававшаяся книга, предок Стандарта:
М. Эллис, Б. Строуструп (так на обложке), Справочное руководство по языку программирования C++ с комментариями. 1992. (aka Annotated Reference Manual, ARM).

Она отличается от основной книги Страуструпа погружением в детали точной семантики и возможной реализации. Хотя язык там сильно устаревший, но кое-какие объяснения вечны, и к сожалению, почти нигде больше не воспроизведены. Например, как устроены виртуальные базовые классы и виртуальные методы в них.

Книжка раритет, несколько лет назад в электронном виде я её искал и не находил. Может, английский вариант доступнее.

Joker_vD в сообщении #556317 писал(а):
Оказывается, при создании объекта сначала вызываются конструкторы базовых классов, сверху вниз, потом конструкторы для полей, которые сами объекты, и лишь потом собственно сам конструктор класса — и это невозможно изменить.А у меня в качестве поля есть объект без конструктора по умолчанию, и инициализировать его можно только после того, как пройдет нетривиальная (с чтением из файла и прочими прелестями) инициализация всех остальных полей. Я-то выкрутился... но сам факт стал очень неприятным сюрпризом.

Да, вот это всё в ARM описано и подчёркнуто.

Впрочем, в стандарте всё это тоже есть, только искать умучаешься. И не "на пальцах", а тяжеловесным канцеляритом.

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение05.04.2012, 00:49 
Joker_vD
По Вашему коду:
Во-первых, конструктор по-умолчанию у DataClass все-таки есть. Он автоматически слеплен компилятором и вызывает конструкторы по умолчанию полей. Вот чтобы он еще и создавал корректный (с т.з. логики работы программы) объект, который потом будет нормально использоваться в программе, может потребоваться его явная реализация.
Во-вторых, объекты каких-либо классов лучше передавать не по значению, а по ссылке. Если они при этом не изменяются в методе, то следует пользоваться ссылкой на константу. Т.е. вместо
Код:
DataClass(vec_ZZ_pE data);
лучше писать
Код:
DataClass(const vec_ZZ_pE& data);
В этом случае не будет создаваться промежуточный объект класса vec_ZZ_pE, а потому и не будет тратиться время на вызов конструктора копирования и деструктора для этого объекта.
В-третьих, все "ненадежные" операции (вроде операций с файлами) лучше выносить за пределы конструкторов, поскольку в этом случае гораздо проще обрабатывать различные исключительные ситуации. Т.е. в конструкторе реализовывать логику по созданию пустого, но рабочего объекта, а загрузку из файла производить в отдельном методе (а не иметь дело с наполовину созданным объектом, если файл не был найден, или у него оказался неверный формат, или в нем оказались некорректные данные).
В-четвертых, вместо конструкции вида
Код:
data = DataClass(t);
можно было просто реализовать и вызвать метод, загружающий данные из vec_ZZ_pE в DataClass (при условии корректно реализованного конструктора по умолчанию у DataClass). Это позволит избежать создания промежуточного объекта типа DataClass и вызова логики оператора присваивания, а также связанных с этим потерь времени.
Joker_vD в сообщении #556362 писал(а):
Любые конструкторы класса vec_ZZ_pE должны вызываться лишь ПОСЛЕ вызова InitZZ
Честно говоря, это как-то странно и попахивает какими-то статическими объектами...
Joker_vD в сообщении #556362 писал(а):
Объект DataClass по смыслу своему не может быть пустышкой — он внутри состоит не из полей типа ZZ_pE*, а из полей ZZ_pE
Замечательно. Что мешает завести также и конструктор по умолчанию для ZZ_pE?

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение05.04.2012, 21:38 

(Оффтоп)

EtCetera в сообщении #556392 писал(а):
Во-первых, конструктор по-умолчанию у DataClass все-таки есть. Он автоматически слеплен компилятором и вызывает конструкторы по умолчанию полей.

А вот и нет. Если в классе явно объявлен хоть один конструктор, неявный конструктор по умолчанию не создается.

Более того, DataClass — "константный". Объект такого типа невозможно изменить после создания (потому-то у него и отсутствует конструктор по умолчанию).

EtCetera в сообщении #556392 писал(а):
В-третьих, все "ненадежные" операции (вроде операций с файлами) лучше выносить за пределы конструкторов, поскольку в этом случае гораздо проще обрабатывать различные исключительные ситуации.

Во-первых, исключение в конструкторе — это нормально. Во-вторых, в данном конкретном случае MainClass жестко связан с файлом. Если файла нет — экземпляр MainClass, соответствующий этому файлу, существовать не должен. Именно поэтому я и не ловил в конструкторе исключения, а намеренно оставил там возможность их появления.

EtCetera в сообщении #556392 писал(а):
Замечательно. Что мешает завести также и конструктор по умолчанию для ZZ_pE?

У ZZ_pE есть конструктор по умолчанию. Однако он не должен вызываться до вызова InitZZ.

EtCetera в сообщении #556392 писал(а):
Честно говоря, это как-то странно и попахивает какими-то статическими объектами...

Что я могу поделать, если ZZ_pE инкапсулирует хитро оптимизированнную арифметику (требующей предвычислений) и вообще принадлежит сторонней библиотеке, которую я не могу править? Кстати, правило "не вызывать конструктор ZZ_pE до вызова InitZZ" крупными буквами прописано как раз в документации к этой библиотеке. Нет, я не могу взять другую библиотеку (других просто нет) или написать свою реализацию.

Давайте закончим этот офф-топ? Я сейчас усилено читаю посоветованную литературу и пытаюсь постичь дзен этого хитросделанного языка... Кстати, может, угадете, как именно я выкрутился (Подсказка: оказывается, именно так и советуют выкручиваться те книжки)?

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение05.04.2012, 21:55 

(Оффтоп)

Joker_vD в сообщении #556744 писал(а):
А вот и нет. Если в классе явно объявлен хоть один конструктор, неявный конструктор по умолчанию не создается.
Точно! Прошляпил.
Joker_vD в сообщении #556744 писал(а):
Кстати, может, угадете, как именно я выкрутился(Подсказка: оказывается, именно так и советуют выкручиваться те книжки)?
Не знаю, как советуют книжки, но я бы просто полем класса сделал не объект типа DataClass, а указатель на него.
Joker_vD в сообщении #556744 писал(а):
Давайте закончим этот офф-топ?
Давайте :-).

 
 
 
 Re: Ищу хороший справочник по C++
Сообщение05.04.2012, 22:07 
Аватара пользователя
Герберт Шилдт, "Самоучитель C++"

 
 
 [ Сообщений: 13 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group