new
, нельзя использовать скобки, если подразумевается вызвать конструктор по умолчанию. То есть нельзя писать: T a();
а надо писать: T a;
так как в первом случае такая запись будет означать декларацию функции a
, которая возвращает тип T
, а далеко не декларацию переменной класса T
с вызовом конструктора по умолчанию. Не спорю, это очевидно для профессионалов. Для новичков же порой подобная "неочевидная" разница вызывает затруднения, поэтому приведу простейший пример, которые расставит все на свои места.
#include <iostream>
class T {
public:
T() { std::cout << "constructor T()"; }
};
int main() {
std::cout << "T a: ";
// Это синтаксис создания экземпляра класса T с вызовом
// конструктора по умолчанию.
T a;
std::cout << std::endl;
std::cout << "T b(): ";
// А вот это декларация функции "b" без аргументов,
// которая возвращает тип T.
T b();
std::cout << std::endl;
return 0;
}
Данная программа напечатает: T a: constructor T()
T b():
Видно, что для T b();
никакой конструктор не был вызван. Что в целом и ожидалось. Использование круглых скобок может быть весьма тонким вопросом в С++.
Другие посты по теме:
"Видно, что для T a(); никакой конструктор не был вызван. Что в целом и ожидалось."
ОтветитьУдалитьСкорее никакой конструктор не был вызван для T b();
Да, опечатка. Спасибо.
ОтветитьУдалитьХотел бы дополнить этот "темный угол" примером из книги Скотта Майерса "Эфективное использование STL".
ОтветитьУдалитьT A( B() ) - объявление функции, которая принимает первым параметром указатель на функцию B f(void). Другими словами - B (f*)(void).
T A( (B()) ) - объявление переменной и вызов конструстора T::T( B ).
Напоролся в своё время несколько раз))
ОтветитьУдалитьНеужели компилятору нормально, что функция объявляется внутри функции?
sanchosz, то есть
ОтветитьУдалитьT A( (void) );
сработает как объявление
переменной с вызовом конструктора?
k06a: Это декларация прототипа фукнции, чтобы ее можно было бы вызвать, например, "b();", а не тела функции как такового.
ОтветитьУдалитьАлександр, ну да. Но тем не менее мне не ясно зачем может понадобиться объявлять прототип функции ВНУТРИ другой функции. Ведь логичнее объявлять прототип выше/ниже какой-нибудь из функций.
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьЕщё надо сказать, что если в T есть конструктор имеющий параметры например T::T(int), то конструкция T b(0); это не декларация функции как может ожидаться, а именно создание объекта b.
ОтветитьУдалить