"Lorenzo_LAMAS" <14979@users.rsdn.ru> wrote in message news:1135391@news.rsdn.ru... > PC>Что писать лучше void fun() чем void fun(void) > Да, естественно. Но я к этому и не придирался. Я не согласен только с > утверждением, что void fun(void) — deprecated в С99/89
только в С99. Как найду официальную paper — покажу. но это где-то было. точно
Здравствуйте, Pavel Chikulaev, Вы писали:
PC>в-третьих (void) deprecated аж с 89 PC>года, но для сохранения обратной PC>совместимости с C эта херь осталась (ЗЫ в С99 она тоже deprecated), в-четвертых PC>понятней особенно для тех кто читает твой код(не этот).
'(void)' для объявления функций без параметров не является deprecated ни в С99, ни в С++ и никаких планов сделать его deprecated, AFAIK, нет.
Здравствуйте, Ignoramus, Вы писали:
LM>>Можно A a;
I>При этом насколько я понимаю не будет вызван дефолтный конструктор, если он явно не определен в А.
Будет или не будет при этом вызван дефолтный конструктор зависит от типа 'A'. Для POD-типов конструктор вызван не будет. Для не-POD классов будет вызван конструктор (неважно, явно он был определен или нет).
I>Например
I>
I>class A
I>{
I> int a;
I>};
I>class B
I>{
I> int b;
I>public:
I> B(void) {b = 0;}
I>}
I>{
I> int a; // значение a неопределено
I> A a; // A::a неопределено
I> B b; // B::b == 0
I> A a(); // если бы так можно было, то A::a == 0
I> B b(); // если бы так можно было, то эквивалентно B b;
I>}
I>
"Андрей Тарасевич" <2174@users.rsdn.ru> wrote in message news:1135405@news.rsdn.ru... > '(void)' для объявления функций без параметров не является deprecated ни в > С99, ни в С++ и никаких планов сделать его deprecated, AFAIK, нет.
(void) не уберут никогда, просто писать в С++ так не рекомендуют, а в С99 —
использовать () как функцую с произвольным количеством параметров.
Здравствуйте, Вадим Никулин, Вы писали:
LM>>>Можно A a;
I>>При этом насколько я понимаю не будет вызван дефолтный конструктор, если он явно не определен в А.
I>>
I>> A a(); // если бы так можно было, то A::a == 0
I>> B b(); // если бы так можно было, то эквивалентно B b;
I>>
I>>Разве не так?
ВН>Так ведь дефолтный конструктор для A ничего не делает! Поэтому A::a не станет равным 0. Все-равно надо явно прописать конструктор по-умолчанию.
Неверно. 'A' в этом примере — POD-тип. Для POD типов инициализатор вида '()' не имеет никакого отношения ни к каким конструкторам. Такой инициализатор просто вызвает дефолтную инициализацию всех подобъектов класса 'A'. Т.е. будет выполнена дефолтная инициализация подобъекта типа 'int', а это именно обнуление.
В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не по линии POD/не-POD, а по линии есть явный конструктор/нет явного конструктора. Но для данного примера это роли не играет.
"Андрей Тарасевич" <2174@users.rsdn.ru> wrote in message news:1135427@news.rsdn.ru... > Неверно. 'A' в этом примере — POD-тип. Для POD типов инициализатор вида '()' > не имеет никакого отношения ни к каким конструкторам. Такой инициализатор > просто вызвает дефолтную инициализацию всех подобъектов класса 'A'. Т.е. будет > выполнена дефолтная инициализация подобъекта типа 'int', а это именно > обнуление. > > В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не > по линии POD/не-POD, а по линии есть явный конструктор/нет явного > конструктора. Но для данного примера это роли не играет.
Здравствуйте, Андрей Тарасевич, Вы писали:
I>>Например
I>>
I>>class A
I>>{
I>> int a;
I>>};
I>>class B
I>>{
I>> int b;
I>>public:
I>> B(void) {b = 0;}
I>>}
I>>{
I>> int a; // значение a неопределено
I>> A a; // A::a неопределено
I>> B b; // B::b == 0
I>> A a(); // если бы так можно было, то A::a == 0
I>> B b(); // если бы так можно было, то эквивалентно B b;
I>>}
I>>
I>>Разве не так?
АТ>Здесь все правильно.
Я здесь не прав. Класс 'A' не является POD-типм, т.к. содержит нестатический private член. Поэтому в С++98 член 'A::a' не будет обнулен инициализатором '()'. Вот если бы класс 'A' был объявлен так
class A
{
public:int a;
};
тогда бы обнуление было.
А в C++98 после TC1 даже исходный вариант будет обнуляться, т.к. у кдасса 'A' нет явного конструктора.
АТ>Здравствуйте, Вадим Никулин, Вы писали:
LM>>>>Можно A a;
I>>>При этом насколько я понимаю не будет вызван дефолтный конструктор, если он явно не определен в А.
I>>>
I>>> A a(); // если бы так можно было, то A::a == 0
I>>> B b(); // если бы так можно было, то эквивалентно B b;
I>>>
I>>>Разве не так?
ВН>>Так ведь дефолтный конструктор для A ничего не делает! Поэтому A::a не станет равным 0. Все-равно надо явно прописать конструктор по-умолчанию.
АТ>Неверно. 'A' в этом примере — POD-тип. Для POD типов инициализатор вида '()' не имеет никакого отношения ни к каким конструкторам. Такой инициализатор просто вызвает дефолтную инициализацию всех подобъектов класса 'A'. Т.е. будет выполнена дефолтная инициализация подобъекта
типа 'int', а это именно обнуление.
Я здесь немножко ошибся. 'A' — не POD тип. Поэтому в С++98 обнуления действительно не будет. А если сделать поле 'A::a' публичным, то будет обнуление.
АТ>В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не по линии POD/не-POD, а по линии есть явный конструктор/нет явного конструктора. Но для данного примера это роли не играет.
Поэтому в пост-TC1 С++ обнуление будет даже в исходном варианте.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
А>>Статическую функцию член класса ещё как можно создавать. L_L>Речь шла о попытке объявить статическую функцию-член класса константной, чего сделать нельзя.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Да, и еще — эта value-инициализация связана именно с выражением вида Type().
Не совсем точно. Value-initialzation связяно именно с инициализатором вида '()'. Например, в выражении 'new Type()' тоже будет происходить value-initialization, но часть 'Type()' при этом назвать "выражением" нельзя, ибо это не так.
Также, как ясно указал автор вопроса (Ignoramus), его запись 'A a();' является "условностью" ("если бы так можно было [объявлять объекты]"). Т.е., если мы соглашаемся на эту условность, то в данном случае тоже должна иметь место value-initialization.
Еще раз замечу, что в оригинальном стандарте C++ (C++98) обнуление поля 'A::a' типа 'int' для инициализатора вида '()' будет происходить, если 'A' является POD-классом. Какой там у этого класса порлучился неявный дефолтный конструктор и что он делает/не делает никакой роли не играет. В исходном примере 'A' не является POD-классом, т.к. 'A' содержит нестатическое private поле. Если бы 'A::a'было public полем, то инициализатор '()' вызывал бы его обнуление даже в С++98, без какой-либо value-initialization.
Здравствуйте, Pavel Chikulaev, Вы писали:
>> Неверно. 'A' в этом примере — POD-тип. Для POD типов инициализатор вида '()' >> не имеет никакого отношения ни к каким конструкторам. Такой инициализатор >> просто вызвает дефолтную инициализацию всех подобъектов класса 'A'. Т.е. будет >> выполнена дефолтная инициализация подобъекта типа 'int', а это именно >> обнуление. >> >> В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не >> по линии POD/не-POD, а по линии есть явный конструктор/нет явного >> конструктора. Но для данного примера это роли не играет.
PC>AFAIK это только по отношению к new T/new T()
Нет. Это по отношению к всем местам в языке, где применим инициализатор вида '()'. Таких мест два: первое — это, как ты сказал, 'new T()', а второе — это выражения вида 'T()'.
Автор вопроса временно условно "ввел" третье место — объявление объекта вида 'T t();'. Именно в рамках этого условного введения я и рассуждал в своем ответе. Все мы прекрасно знаем, что это на самом деле не объявление объекта, но речь сейчас не о том.
АТ>Не совсем точно. Value-initialzation связяно именно с инициализатором вида '()'. Например, в выражении 'new Type()' тоже будет происходить value-initialization, но часть 'Type()' при этом назвать "выражением" нельзя, ибо это не так.
Да, я думал как назвать Type() и опрометчиво взял слово "выражение" из 5.2.3/2
The expression T(), where T is a simple-type-specifier ....
мне следовало написать именно инициализатор, либо "выражение" в кавычках, т.е. не в том смысле, как это слово используется в стандарте.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Андрей Тарасевич, Вы писали:
L_L>>С другой стороны, думается мне, словосочетание "инициализатор вида" не подходит к такому
L_L>>
L_L>>#include <iostream>
L_L>>class A
L_L>>{
L_L>>public:
L_L>> virtual ~A(){}
L_L>> int i_;
L_L>>};
L_L>>int main()
L_L>>{
L_L>> std::cout<<A().i_<<std::endl;
L_L>>}
L_L>>
АТ>Почему не подходит?
А, понял. Ты прав. Формально в данном случае мы имеем частный случай явного приведения типа в функциональной нотации.
Тогда, чтобы быть уж совсем точным: value-initialization применимо к инициализатору '()' (это, например, 'new T()' и 'm()' для поля 'm' в списке инициализации конструктора) и к функциональному приведению типа вида 'T()'.
Здравствуйте, Андрей Тарасевич, Вы писали:
>>> В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не >>> по линии POD/не-POD, а по линии есть явный конструктор/нет явного >>> конструктора. Но для данного примера это роли не играет.
PC>>AFAIK это только по отношению к new T/new T()
АТ>Нет. Это по отношению к всем местам в языке, где применим инициализатор вида '()'. Таких мест два: первое — это, как ты сказал, 'new T()', а второе — это выражения вида 'T()'.
Есть еще третье место: инициализация поля класса в списке инициализаторов в конструкторе класса.