У меня возникла проблема с пониманием синтаксиса. Увидел вот такой конструктор:
foo(char *msg) : msg(msg) { ..... }
Что значит двоеточие после аргумента в первых скобках?
Область кода за двоеточием и до начала тела конструктора называется инициализатором конструктора.
Используется как для инициализации членов класса, так и для вызова конструктора базового/базовых классов, т.е. по сути, инициализации базовой составляющей. Также здесь может быть вызов другого конструктора текущего класса (делегирование конструкторов, начиная с c++11).
Без инициализатора конструктора не обойтись, если в классе присутствует член ссылочного типа или константа, или член класса, у которого нет конструктора по умолчанию:
struct S {
S(int) {} // Конструктор с параметром. Не является конструктором по умолчанию.
};
class B {
public:
B(int i) : i(i), r(i), s(i) {
// this->i = i; // Ошибка. Нельзя присваивать константе.
// r = i; // Ошибка. Не является инициализацией ссылки.
// s = S(i); // Ошибка. `s` должен быть создан в инициализаторе конструктора.
}
private:
const int i;
int& r;
S s;
};
т.к. код, начинающийся за фигурной скобкой будет приводить уже не к инициализации члена, а к присваиванию ему значения, чего нельзя сделать для упомянутых ранее ссылок или констант.
Дополнительно стоит заметить (как было упомянуто в комментарии Monah Tuk), что если член-класса не инициализирован явно в инициализаторе конструктора и при этом ему присваивается значение в теле конструктора, то он сначала будет инициализирован конструктором по умолчанию (или инициализацией в определении класса (c++11)):
class D {
int i = 42; // Инициализация члена в определении класса
};
После чего выполнится присваивание в теле конструктора. Для сложных классов это может приводить к дополнительным расходам.
Т.о. инициализацию членов стоит производить либо в определении класса, либо в инициализаторе конструктора. Не стоит пытаться сделать нечто подобное непосредственно внутри тела конструктора.
class foo
{
public:
foo(int a) : a(a) {}
// эквивалентно foo(int a) { this->a = a; }
private:
int a;
}
Это вообще-то база синтаксиса определения конструкторов в плюсах.
Еще может быть:
class foo : public bar
{
public:
foo(int a) : bar(a) { ... }
}
В этом случае, после двоеточия вызывается конструктор базового класса. ЕМНИП (могу ошибаться), в случае базового класса это единственный верный способ его вызова, т.е. написать вот так:
foo(int a) { bar(a); ... }
будет неверно.
П.С. Думаю, ответ alexolut более полон, чем мой.
Это использование списка инициализации (Initialization List) для конструктора. Эта запись эквивалентна строчке кода в начале конструктора
this->msg = msg;
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Подскажите, пожалуйста, как сделать, чтобы слова из массива выводились в таком виде: то есть, чтобы на строчку влезало разное количество слов,...
У меня есть плеер, в котором можно скачивать песниДля скачивания на данный момент я использую IntentService, который выглядит вот так:
До перезагрузки компьютера всё работало отличноПосле перезагрузки netbeans пишет ошибку при компиляции проекта