2014 dxdy logo

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

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




Начать новую тему Ответить на тему
 
 Ищу хороший справочник по C++
Сообщение01.04.2012, 21:21 
Заслуженный участник


09/09/10
3729
Причем хотелось бы, чтобы он был "концентрированный", с кучей перекрестных ссылок. И подробный чтоб! Например, если рассказывает про слово 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 


20/12/11
44
Стандарт смотрели? Думаю, что смотрели. Но так, на всякий случай: C++ Standard - ANSI ISO IEC 14882, Second edition 2003-10-15.pdf и 14882:2011.
Все здесь.

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение02.04.2012, 16:33 
Заслуженный участник


09/09/10
3729
Да, у меня есть копия стандарта. Но он настолько нудный, что...

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение02.04.2012, 17:08 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Такой книги пока не написано (есть такие, которые содержат эту информацию, но в другом порядке изложенную). Напишите вы!

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

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 21:50 
Заслуженный участник


09/09/10
3729
Munin в сообщении #554870 писал(а):
(есть такие, которые содержат эту информацию, но в другом порядке изложенную)

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

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

(Оффтоп)

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

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 22:15 


20/12/11
44
Читали Саттера, Майерса?
    Герб Саттер. Решение сложных задач на С++.
    Скотт Майерс. Эффективное использование С++.
У них несколько книг с похожими названиями.

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 22:46 
Заслуженный участник


28/04/09
1933
Joker_vD в сообщении #556317 писал(а):
когда мне вызывать конструкторы базовых классов и вызывать ли их вообще
Простой порядок "конструирования" полей совпадает с порядком их объявления в классе (а не с порядком конструкторов в списке инициализации). Порядок вызова конструкторов базовых классов при множественном наследовании совпадает с порядком этих классов в списке наследования. Если же требуется наличие какой-либо более сложной логики вызова конструкторов, необходимо убедиться, что для всех нужных полей есть конструкторы по умолчанию, и реализовывать эту логику собственно в теле конструктора данного класса. Все очень просто и гибко.
Фраза же по поводу "вызывать ли их вообще" кажется мне весьма опасной. Лично я не могу себе представить, в каком случае может не понадобиться вызов хоть какого-нибудь конструктора...

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение04.04.2012, 23:33 
Заслуженный участник


09/09/10
3729
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 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Joker_vD в сообщении #556317 писал(а):
Может, дадите парочку наименований?

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

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

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

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

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

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

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

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

 Профиль  
                  
 
 Re: Ищу хороший справочник по C++
Сообщение05.04.2012, 00:49 
Заслуженный участник


28/04/09
1933
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 
Заслуженный участник


09/09/10
3729

(Оффтоп)

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 
Заслуженный участник


28/04/09
1933

(Оффтоп)

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

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


29/07/05
8248
Москва
Герберт Шилдт, "Самоучитель C++"

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group