Топ контрибуторов
loading
loading
Знаете ли Вы, что

Вы можете подписаться на RSS ленту новых тестов сервиса Quizful, в том числе и отдельно по каждой категории

Лента обновлений
ссылка May 18 13:25
Комментарий от MAX200688:
А как же неявный вызов конструктора родительского клас...
ссылка May 17 20:56
Комментарий от motya:
И лишнюю точку с запятой поставить, чтобы народ сетовал
ссылка May 17 20:49
Комментарий от motya:
Программы не существует
ссылка May 17 07:00
Комментарий от IWind:
Вот это бред, а не вопрос, автор вопроса ты был под чем?
ссылка May 16 21:33
Комментарий от kaput182:
Ужасно сформулированное условие.
Статистика

Тестов: 153, вопросов: 8595. Пройдено: 433514 / 2126322.

Основы C++ (part 1)

head tail Статья
категория
C++
дата15.05.2009
авторanalizer
голосов47

- Ваши зарплатные ожидания?
- ... тысяч. [в два раза выше средней з/п по городу]

с одного проваленного собеседования

Рекомендуемая литература:

Препроцессор в C++

NB: Конструкция #define func(args) ... не определяет функцию (как многие полагают), а только правило макроподстановки. То есть код:

#define sqr(x) x*x
int y = 5;
int z = sqr(y+1);

не будет вычислять квадрат шести и класть его в z, вместо этого после отработки препроцессора последняя строчка превратится в:

int z = y+1*y+1;

Это всё что сделает макрос sqr. Т.е. в z окажется 11, а никак не 36.

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

Ключевое слово static

NB: В С/С++ имеется порядка пяти-шести (в зависимости от версии стандарта) применений ключевого слова static:

  1. Глобальная переменная, объявленная с ключевым словом static, будет иметь internal linkage. Таким образом использование static помогает избавиться от ошибок линковки из-за того что в разных объектах трансляции были объявлены глобальные переменные с одинаковыми именами. (Замечу что наличие глобальных переменных скорее всего свидетельствует об ошибках проектирования. В крайнем случае следует использовать синглтоны.)
  2. Глобальная функция, объявленная с ключевым словом static, будет также иметь internal linkage. Собственно - см. выше. Наличие глобальных функций об ошибках проектирования не свидетельствует... как правило.
  3. Локальная переменная, объявленная с ключевым словом static, будет иметь локальную область видимости и время жизни - от инициализации до завершения программы. Инициализация локальной статической переменной будет происходить в тот момент когда выполнение программы пройдёт через строчку с объявлением переменной. Если конструктор локальной статической переменной выбросит исключение (которое будет обработано), то при следующем прохождении этой строчки будет также выполнена попытка инициализации переменной. Если инициализация статической локальной переменной прошла успешно, инициализации более происходить не будет. По-умолчанию, статические переменные POD-типов инициализируются нулями.
  4. Переменная-член класса, объявленная с ключевым словом static, будет иметь глобальную область видимости (через класс, разумеется) и время жизни - от инициализации до завершения программы. Инициализация статических переменных-членов происходит так же как и глобальных переменных: в глобальной области видимости объявляется тип переменной, затем её имя (с указанием класса в котором она содержится), и, опционально, инициализатором: int MyClass::variable_ = 5; По-умолчанию, статические переменные-члены также будут инициализированы нулями.
  5. Функция-член класса, объявленная с ключевым словом static, будет иметь глобальную область видимости. В отличие от других функций-членов, статический метод не будет получать указатель на текущий объект и соотвественно не может быть объявлен со спецификаторами const или virtual, по этой же причине статические методы не имеют прямого доступа к нестатическим полям класса.
  6. ISO/IEC 9899:TC2
    6.7.5.3 Function declarators (including prototypes)
    7    ... If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

    Т.е. (как я это понял) ключевое слово static в объявлении функции, внутри указания размера массива, обозначает что размер массива может быть любой, но не менее чем из указанного после слова static количества элементов. Разобраться с данным применением у меня пока не было возможности, буду благодарен если кто-то выложит пример в котором покажет отличия вызываемые наличием этого ключевого слова. Гцц похоже его игнорирует, а Visual C++ стандарт C99 вообще не признаёт.

Список инициализации в C++

NB: Единственный способ инициализировать константные поля, поля-ссылки и вызвать конструкторы родительских классов с определёнными параметрами - список инициализации. Список инициализации отделяется от прототипа конструктора двоеточием и состоит из инициализаторов разделённых запятыми. Например он может выглядеть так:

struct A
{
	A(int){}
};

struct B : A
{
	const int c_;
	unsigned d_;
	unsigned& r_;
	B() : A(5), c_(4), r_(d_)
	{
		d_ = 5;
	}
};

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

Ключевое слово const

Просто факты... о которых не все знают:

  1. Ключевое слово const перед объявлением массива или указателя относится к элементам массива, а не самой переменной-массиву. Т.е. const int* p; указывает на элемент типа const int и его значение нельзя изменять. При этом ничто не запрещает изменять значение самого указателя, если хотите это запретить - напишите const после "звёздочки".
  2. Любой тип T приводим к типу const T, массивы из элементов таких типов также приводимы, так что не стоит волноваться из-за того что у вас указатель на строку типа char*, а функция принимает в себя аргумент типа const char*. Вообще слова const и static в объявлениях функций следует расставлять строго до тех пор пока программа не прекратит компилироваться. Я ещё ни разу не видел чтобы компилирующаяся программа переставала правильно работать от расстановки const и static (на нормальных компиляторах). Винт закручивается следующим образом: до срыва, затем пол-оборота назад.
  3. Ключевое слово const перед структурой или классом, по сути, добавляет ключевое слово const ко всем его полям. Исключение составляют поля-ссылки, поля объявленные с ключевым словом mutable и статические поля. Т.е., для примера выше, следующий код будет успешно скомпилирован (и, по идее, изменит значение поля d_):
    const B b;
    b.r_=7;
  4. Константные методы отличаются от неконстантных лишь тем что указатель this имеет тип не T* const, а const T* const со всеми вытекающими отсюда последствиями. Неконстантные методы не могут быть вызваны у объектов являющимися константными.

К чему эпиграф собственно? В конце марта - начале апреля, мне пришлось принять немало собеседований по Си и С++ и я был несколько удивлён тому уровню знаний, что есть у людей, и теми деньгами, которые они за эти знания хотят получать (возможно что это проблема лишь моего района замкадья). Если у вас нет знания английского - средняя зарплата по городу - ваш потолок навек (и то в лучшем случае). Если вы понимаете, что ваше знание языка программирования не идеально, но при этом пишете его в резюме - будьте добры, перечитайте книжку по конструкциям языка, можно не затрагивая стандартную библиотеку. Пара недель чтения по вечерам стоят дополнительных $300 - $500 в месяц. Ученье - свет... и право вставать на работу уже после того как рассветёт.

----

Дмитрий analizer Потапов, май 2009

Если Вам понравилась статья, проголосуйте за нее

Голосов: 47  loading...
clumsy   elw00d   Gluttton   serj   valyala   glukin   albs   Nilud   gok   nebel1000   toxx   Toster   Rastamanka   Kanesy   belykh   Arche   matroskin127   Zeus   article113   Janry   Kiirk   salvequick   guguk   Radium   Mariatomeyan   inspirer91   viperff   DTSAR   lalilulala   Alexone007   dekartlv   rihtar   COLDPLAY   Yar   ijedo   violet23   SunDrop   YPedorenko   Staller   Phantom93   alexey_popov   anti_k   a_derkach1992   Geryon   TASbKA   modus_exciter   SorcererLoL