Re[12]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 11:26
Оценка: 6 (1)
ВН>ok. Теперь уже запутался я. А что такое тогда value-initialization? Если можно, со ссылкой на стандарт.

стандарт нужен не 1998 года, с поправками. value — initialization вкратце означает, что при отсутствии явно определенного дефолтного конструктора будут вызваны конструкторы для баз и подобъектов-членов и т.д. и т.п., но главное в нашем обсуждении, будет выполнена value инициализация для членов встроенных типов, которая сведется к zero-инициализации. Копировать из моей версии стандарта нельзя (она бумажная ) а потому ссылки:
в revisions это страница 18, 20, 33.

А если ссылками, это 5.2.3/2, 5.3.4/15, 8.5/5
Of course, the code must be complete enough to compile and link.
Re: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 09:24
Оценка: 4 (1)
I>что означает что функция f не может менять данные члены класса А. (Кстати, насколько я понимаю также не может вызывать не-const методы вложенных классов, однако может вызывать не-const методы классов, вложенных через указатель. Правильно?)

Не совсем понятно, что ты имеешь в виду под вложенными классами. Предположу, что речь идет о членах-данных

class A{/*...*/}; 
class B{/*...*/};

class C
{
  A a_;
  B b_;

  void fun()const;
};

Если ты об этом, то да — в fun нельзя будет вызвать неконстантные функции-члены соответствующих классов.
Если a_ или b_ будет объявлен как mutable — то можно. Если они будут указателями (A * a_, B * b_) или ссылками — то опять же, можно.

I>интересуют такие вопросы:


I>1. Можно ли объявлять глобальную функцию (не член класса) как "int g(void) const". Думается что нет, т.к. не вижу смысла. Если да, то что это значит?


Нет, нельзя. Так же как и статическую функцию-член класса нельзя.

I>2. Можно ли объявлять функцию или метод как "const int g(void)"? Т.е. может ли функция возвращать константный объект? В каких случаях это может применяться?


Да, можно, но особого смысла в этом нет — то, что ты возвращаешь const int — будет r-value встроенного типа, поменять ты его не сможешь, даже если он неконстантный. Зато такая константность может понадобиться для объектов определенных тобой типов, чтоб для них (возвращаемых объектов) нельзя было вызвать неконстантные функции.

I>3. Если 2, то возможна ли комбинированная конструкция const int g(void) const?

Да, конечно, для нестатической функции-члена класса.
Of course, the code must be complete enough to compile and link.
Re[3]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 09:50
Оценка: 4 (1)
I>Да я имел в виду именно это. А как еще это можно было понять/назвать?
Есть еще понятие вложенного класса

class A
{
   class NestedInA{};
};


I>т.е. если я правильно понял это можно использовать например чтобы

I>Так?

Да, например так

I>Кроме того, наверное нельзя будет присвоить

I>
I> A a(); 
I> const B b = a.get_b();            // ok
I> B bb = a.get_b();                 // compiler error!
I>


I>Правильно я понял?


Ээээ, тут о присваивании речь не идет — в обоих случаях ОК и в обоих случаях это не присваивание, а инициализация копированием. Кроме того, A a(); — это объявление функции, а не объекта. И потому до ОК дело не дойдет, не скомпилится

class A
{
public:
   A & operator = (int){return *this;}
};

const A fun(){return A();}

int main()
{
   fun() = 1;
}

Вот скорее про такое присваивание ты говорил
Of course, the code must be complete enough to compile and link.
Re[11]: const и функции
От: Вадим Никулин Россия Здесь
Дата: 20.04.05 11:08
Оценка: +1
Здравствуйте, Lorenzo_LAMAS, Вы писали:

I>>А я думал что дефолтный конструктор все обнуляет... Правда, никогда на это не рассчитывал и всегда писал его явно


L_L>Неявный дефолтный конструктор, сгенеренный компилятором, может сделать следующее : вызвать конструкторы базовых классов, членов-данных и, например, установить указатель на таблицу виртуальных функций. Но он не будет занулять данные встроенных типов — тебе придется писать для этого конструктор самому.


ok. Теперь уже запутался я. А что такое тогда value-initialization? Если можно, со ссылкой на стандарт.
Re[2]: const и функции
От: Аноним  
Дата: 21.04.05 05:23
Оценка: -1
Здравствуйте, Lorenzo_LAMAS, Вы писали:

I>>1. Можно ли объявлять глобальную функцию (не член класса) как "int g(void) const". Думается что нет, т.к. не вижу смысла. Если да, то что это значит?


L_L>Нет, нельзя. Так же как и статическую функцию-член класса нельзя.


Статическую функцию член класса ещё как можно создавать.

class A
{
public:
     static int sfuncA()
     {
         return 3; // всё в порядке
         return i_; // а вот тут ошибка компилятора, т.к. статическая функция класса не имеет доступа к переменным и к this.
     }
private:
     int i_;
}

A * a = NULL;
int b = a->sfuncA(); // ошибки нет, даже с учётом того, что указатель NULL;


Обычно статическая функция создаётся для запуста нового потока, и в качестве поточной функции используется статическая функция

static int MyClass::start(MyClass * object);
Re[18]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 18:37
Оценка: +1
Здравствуйте, Андрей Тарасевич, Вы писали:

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()'.
Best regards,
Андрей Тарасевич
const и функции
От: Ignoramus  
Дата: 20.04.05 09:16
Оценка:
У Страуструпа нашел только такое применение const с функциями:

[code]
class A
{
...
public:
int f(void) const;
};
[/ccode]

что означает что функция f не может менять данные члены класса А. (Кстати, насколько я понимаю также не может вызывать не-const методы вложенных классов, однако может вызывать не-const методы классов, вложенных через указатель. Правильно?)

интересуют такие вопросы:

1. Можно ли объявлять глобальную функцию (не член класса) как "int g(void) const". Думается что нет, т.к. не вижу смысла. Если да, то что это значит?

2. Можно ли объявлять функцию или метод как "const int g(void)"? Т.е. может ли функция возвращать константный объект? В каких случаях это может применяться?

3. Если 2, то возможна ли комбинированная конструкция const int g(void) const?
Re[2]: const и функции
От: Ignoramus  
Дата: 20.04.05 09:34
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Не совсем понятно, что ты имеешь в виду под вложенными классами. Предположу, что речь идет о членах-данных


L_L>
L_L>class A{/*...*/}; 
L_L>class B{/*...*/};

L_L>class C
L_L>{
L_L>  A a_;
L_L>  B b_;

L_L>  void fun()const;
L_L>};
L_L>

L_L>Если ты об этом, то да — в fun нельзя будет вызвать неконстантные функции-члены соответствующих классов.
L_L>Если a_ или b_ будет объявлен как mutable — то можно. Если они будут указателями (A * a_, B * b_) или ссылками — то опять же, можно.

Да я имел в виду именно это. А как еще это можно было понять/назвать?

I>>интересуют такие вопросы:


I>>1. Можно ли объявлять глобальную функцию (не член класса) как "int g(void) const". Думается что нет, т.к. не вижу смысла. Если да, то что это значит?


L_L>Нет, нельзя. Так же как и статическую функцию-член класса нельзя.


Ну и слава богу .

I>>2. Можно ли объявлять функцию или метод как "const int g(void)"? Т.е. может ли функция возвращать константный объект? В каких случаях это может применяться?


L_L>Да, можно, но особого смысла в этом нет — то, что ты возвращаешь const int — будет r-value встроенного типа, поменять ты его не сможешь, даже если он неконстантный. Зато такая константность может понадобиться для объектов определенных тобой типов, чтоб для них (возвращаемых объектов) нельзя было вызвать неконстантные функции.


т.е. если я правильно понял это можно использовать например чтобы

class B
{
 int f(void);
}

class A
{
 B b;
public:
 const B& get_b(void) {return b;}
};

...
{
 A a();
 a.get_b().f();        // compiler error!
}



Так?

Кроме того, наверное нельзя будет присвоить
 A a();
 const B b = a.get_b();            // ok
 B bb = a.get_b();                 // compiler error!


Правильно я понял?
Re: const и функции
От: LuciferMoscow Россия  
Дата: 20.04.05 09:48
Оценка:
I>2. Можно ли объявлять функцию или метод как "const int g(void)"? Т.е. может ли функция возвращать константный объект? В каких случаях это может применяться?
Один пример уже приводили const SomeObj& CClass::GetSome();
Второй пример — постфиксный оператор++
I>3. Если 2, то возможна ли комбинированная конструкция const int g(void) const?
да
Re[3]: const и функции
От: jazzer Россия Skype: enerjazzer
Дата: 20.04.05 09:49
Оценка:
Здравствуйте, Ignoramus, Вы писали:

I>Кроме того, наверное нельзя будет присвоить

I>
I> A a();
I> const B b = a.get_b();            // ok
I> B bb = a.get_b();                 // compiler error!
I>


I>Правильно я понял?


Нет. На присваивание это не действует (а то, что ты написал — это вообще инициализация, а не присваивание).
запретить только можно будет инициализацию некостантных ссылок в стиле B& bb = a.get_b();
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:18
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Ignoramus, Вы писали:


I>>Кроме того, наверное нельзя будет присвоить

I>>
I>> A a();
I>> const B b = a.get_b();            // ok
I>> B bb = a.get_b();                 // compiler error!
I>>


I>>Правильно я понял?


J>Нет. На присваивание это не действует (а то, что ты написал — это вообще инициализация, а не присваивание).

J>запретить только можно будет инициализацию некостантных ссылок в стиле B& bb = a.get_b();

сорри, в данном примере я ошибся, я имел в виду конечно const B& b и B& bb.

Но если бы я объявил A::get_b как B get_b(), то тогда с помощью const также можно запретить инициализацию и самого объекта, правильно?

Кроме того если пример B bb = a.get_b(); разбить на B bb; bb = a.get_b();, то это тоже компилятор не пропустит, так? Т.е. не только инициализация но и присваивание запрещено? (для const B b понятно может быть только инициализация).
Re[4]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:19
Оценка:
Здравствуйте, jazzer, Вы писали:

Упс, пропустил вот это:
J>Нет. На присваивание это не действует

А почему?
Re[5]: const и функции
От: Вадим Никулин Россия Здесь
Дата: 20.04.05 10:23
Оценка:
Здравствуйте, Ignoramus, Вы писали:

I>Упс, пропустил вот это:

J>>Нет. На присваивание это не действует

I>А почему?


Mr. jazzer хотел сказать, что на каноническую форму присваивания это не действует.

Каноническая форма конструктора копирования:
Obj( const Obj & );

Каноническая форма присваивания:
Obj &operator = ( const Obj & );
Re[4]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:26
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

I>>Да я имел в виду именно это. А как еще это можно было понять/назвать?

L_L>Есть еще понятие вложенного класса

L_L>
L_L>class A
L_L>{
L_L>   class NestedInA{};
L_L>};
L_L>


Теперь понял . Честно говоря никогда так не делал. Это реально используется? Этот класс будет доступен для инстанциации вне класса А?

И это получается только объявление класса можно поместить как вложенное или после него сразу должно следовать определение члена? типа

class A
{
 class NestedInA{} na;
}


L_L>Ээээ, тут о присваивании речь не идет — в обоих случаях ОК и в обоих случаях это не присваивание, а инициализация копированием.

Согласен, я за это уже ответил .
Кстати меня всегда интересовал вопрос — что происходит если я пишу
A a = A();

При этом некоторое время существует 2 экземпляра А или создается только один? Подозреваю что это зависит от интеллектуальности компилятора.

L_L>Кроме того, A a(); — это объявление функции, а не объекта. И потому до ОК дело не дойдет, не скомпилится

Не согласен. Я ведь не переопределил оператор (), так что это просто вызов конструктора без параметров.
Re[6]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:29
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, Ignoramus, Вы писали:


I>>Упс, пропустил вот это:

J>>>Нет. На присваивание это не действует

I>>А почему?


ВН>Mr. jazzer хотел сказать, что на каноническую форму присваивания это не действует.


ВН>Каноническая форма конструктора копирования:

ВН>Obj( const Obj & );

ВН>Каноническая форма присваивания:

ВН>Obj &operator = ( const Obj & );

Ну Вы меня совсем запутали На что действует и на что не действует?
Re[5]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 10:36
Оценка:
I>Теперь понял . Честно говоря никогда так не делал. Это реально используется? Этот класс будет доступен для инстанциации вне класса А?

Ээээ, зависит от того, как ты его определил.

class A
{
  class NestedInA{};
};

A::NestedInA a; // ошибка, так как вложенный класс недоступен

class B
{
public:
   class NestedInB{};
};

B::NestedInB b; //нормально


ну и т.д. по поводу возможности "инстанцирования вне класса А" — тут, как это часто бывает в С++, чтоб получить исчерпывающий ответ лучше посмотреть определение языка.

I>И это получается только объявление класса можно поместить как вложенное или после него сразу должно следовать определение члена? типа


I>
I>class A
I>{
I> class NestedInA{} na;
I>}
I>


Ты можешь так сделать, но ты вовсе не обязан так делать.

I>Кстати меня всегда интересовал вопрос — что происходит если я пишу

I>
I>A a = A();
I>

I>При этом некоторое время существует 2 экземпляра А или создается только один? Подозреваю что это зависит от интеллектуальности компилятора.

Да, у тебя тут инициализация копированием, но компилятор вполне может соптимизировать — убрать ненужное копирование.

I>Не согласен. Я ведь не переопределил оператор (), так что это просто вызов конструктора без параметров.


От твоего согласия тут увы, ничего не зависит. Попробуй скомпили такое :

struct A{
   void fun(){}
};

int main()
{
   A a();
   a.fun();
}


после этого, мы обсудим, с чем ты несогласен
Of course, the code must be complete enough to compile and link.
Re[5]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:37
Оценка:
L_L>>Кроме того, A a(); — это объявление функции, а не объекта. И потому до ОК дело не дойдет, не скомпилится
I>Не согласен. Я ведь не переопределил оператор (), так что это просто вызов конструктора без параметров.

Блин, попробовал, реально получается что компилятор думает что это объявление функции. Вот если конструктор с параметром, то уже так не думает.

Как же так? Получается нельзя инстанциировать экземпляр класса вызвав его конструктор по умолчанию, если он не определен в классе. Выглядит как исключение из правил инициализации?
Re[6]: const и функции
От: LuciferMoscow Россия  
Дата: 20.04.05 10:39
Оценка:
Здравствуйте, Ignoramus, Вы писали:
I>Как же так? Получается нельзя инстанциировать экземпляр класса вызвав его конструктор по умолчанию, если он не определен в классе. Выглядит как исключение из правил инициализации?
Можно A a;
Re[6]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 10:43
Оценка:
I>Как же так? Получается нельзя инстанциировать экземпляр класса вызвав его конструктор по умолчанию, если он не определен в классе. Выглядит как исключение из правил инициализации?

В теле функции ты можешь объявить функцию, а потому "выражение" вида A a(); это объявление функции.

Бывают случаи похуже и менее очевидные — это следствие синтаксической неоднозначности (если так можно выразиться).

class A
{
public:
   A(int);
};

int main()
{
   double d = 1.;
   A nonObj(int(d));// - это опять объявление функции, возвращающей А и принимающей целое
   A nonObj1(int()); // и даже это - объявление функции, ее параметр - указатель на функцию
   A obj((int)d); // вот это объект
}
Of course, the code must be complete enough to compile and link.
Re[7]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:46
Оценка:
Здравствуйте, LuciferMoscow, Вы писали:

LM>Можно A a;


При этом насколько я понимаю не будет вызван дефолтный конструктор, если он явно не определен в А.

Например

class A
{
 int a;
};
class B
{
 int b;
public:
 B(void) {b = 0;}
}

{
 int a;   // значение a неопределено
 A a;     // A::a неопределено
 B b;     // B::b == 0
 A a();   // если бы так можно было, то A::a == 0
 B b();   // если бы так можно было, то эквивалентно B b;
}


Разве не так?
Re[8]: const и функции
От: Вадим Никулин Россия Здесь
Дата: 20.04.05 10:50
Оценка:
Здравствуйте, Ignoramus, Вы писали:

I>Здравствуйте, LuciferMoscow, Вы писали:


LM>>Можно A a;


I>При этом насколько я понимаю не будет вызван дефолтный конструктор, если он явно не определен в А.


I>
I> A a();   // если бы так можно было, то A::a == 0
I> B b();   // если бы так можно было, то эквивалентно B b;
I>


I>Разве не так?


Так ведь дефолтный конструктор для A ничего не делает! Поэтому A::a не станет равным 0. Все-равно надо явно прописать конструктор по-умолчанию.
Re[7]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:52
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:


L_L>Бывают случаи похуже и менее очевидные — это следствие синтаксической неоднозначности (если так можно выразиться).


Век живи, век учись, сказал поручик. Короче говоря я так понял, у объявлений функции есть приоритет при разрешении неоднозначностей, так?
Re[9]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 10:52
Оценка:
ВН>Так ведь дефолтный конструктор для A ничего не делает! Поэтому A::a не станет равным 0. Все-равно надо явно прописать конструктор по-умолчанию.

Либо использовать value-initialization, при условии, что твой компилятор знает, что это такое
A a = A();
std::cout<<A().a<<std::endl;
Of course, the code must be complete enough to compile and link.
Re[7]: const и функции
От: Вадим Никулин Россия Здесь
Дата: 20.04.05 10:54
Оценка:
Здравствуйте, Ignoramus, Вы писали:

ВН>>Mr. jazzer хотел сказать, что на каноническую форму присваивания это не действует.


I>Ну Вы меня совсем запутали На что действует и на что не действует?


Вот что было написано у тебя:
 A a;                              // круглые скобки удалены :)
 const B b = a.get_b();            // ok
 B bb = a.get_b();                 // compiler error! (1)


В строчке (1) вызывается конструктор копирования B. По-умолчанию он принимает const B &. Соответственно, никакой ошибки не будет, т. к. a.get_b() приводится к типу const B &.
Re[9]: const и функции
От: Ignoramus  
Дата: 20.04.05 10:55
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Так ведь дефолтный конструктор для A ничего не делает! Поэтому A::a не станет равным 0. Все-равно надо явно прописать конструктор по-умолчанию.


А я думал что дефолтный конструктор все обнуляет... Правда, никогда на это не рассчитывал и всегда писал его явно
Re[8]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 10:56
Оценка:
I>Век живи, век учись, сказал поручик. Короче говоря я так понял, у объявлений функции есть приоритет при разрешении неоднозначностей, так?

Да, если есть неоднозначность между выражением и объявлением, то она разрешается в пользу объявления — Бьярн, кстати, пишет об этом в книжке.
Of course, the code must be complete enough to compile and link.
Re[10]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 11:00
Оценка:
I>А я думал что дефолтный конструктор все обнуляет... Правда, никогда на это не рассчитывал и всегда писал его явно

Неявный дефолтный конструктор, сгенеренный компилятором, может сделать следующее : вызвать конструкторы базовых классов, членов-данных и, например, установить указатель на таблицу виртуальных функций. Но он не будет занулять данные встроенных типов — тебе придется писать для этого конструктор самому.
Of course, the code must be complete enough to compile and link.
Re[13]: const и функции
От: Lorenzo_LAMAS  
Дата: 20.04.05 11:30
Оценка:
Да, и еще — эта value-инициализация связана именно с выражением вида Type().
Of course, the code must be complete enough to compile and link.
Re[7]: const и функции
От: jazzer Россия Skype: enerjazzer
Дата: 20.04.05 11:41
Оценка:
Здравствуйте, Ignoramus, Вы писали:

I>>>А почему?


ВН>>Mr. jazzer хотел сказать, что на каноническую форму присваивания это не действует.


ВН>>Каноническая форма конструктора копирования:

ВН>>Obj( const Obj & );

ВН>>Каноническая форма присваивания:

ВН>>Obj &operator = ( const Obj & );

I>Ну Вы меня совсем запутали На что действует и на что не действует?


Mr. Вадим Никулин хотел сказать, что, помимо "канонических" форм конструктора копирования и оператора присваивания, имеющих аргументом константную ссылку, если "неканонические" с неконстантной ссылкой (например, таков класс std::auto_ptr), и вот для них-то это работать и не будет
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: const и функции
От: Pavel Chikulaev Россия  
Дата: 20.04.05 18:36
Оценка:
"Ignoramus" <18039@users.rsdn.ru> wrote in message news:1133667@news.rsdn.ru...
> int f(void) const;
Маленький совет не в тему: пиши f() вместо f(void) потому что во-первых короче,
во-вторых ты используешь пережитки из C, в-третьих (void) deprecated аж с 89
года, но для сохранения обратной
совместимости с C эта херь осталась (ЗЫ в С99 она тоже deprecated), в-четвертых
понятней особенно для тех кто читает твой код(не этот).

ЗЫ: А в Whidbey так и будет показывать войд — Майкрософт сказала, что исправит
это в следующей версии (где-нить в 2007... )

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[2]: const и функции
От: Ignoramus  
Дата: 20.04.05 21:59
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>Маленький совет не в тему: пиши f() вместо f(void) потому что во-первых короче,

PC>во-вторых ты используешь пережитки из C, в-третьих (void) deprecated аж с 89
PC>года, но для сохранения обратной
PC>совместимости с C эта херь осталась (ЗЫ в С99 она тоже deprecated), в-четвертых
PC>понятней особенно для тех кто читает твой код(не этот).

У меня почему-то обратная ассоциация была, что когда я пишу f(), то как бы использую пережиток из С в виде произвольного числа аргументов. Просмотрел Страуструпа, но не нашел советов на этот счет, хотя почему-то запомнилось что что-то было, видимо глюк в памяти. Будем считать, Вы меня убедили .
Re[3]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 06:44
Оценка:
А>Статическую функцию член класса ещё как можно создавать.
Речь шла о попытке объявить статическую функцию-член класса константной, чего сделать нельзя.
Of course, the code must be complete enough to compile and link.
Re[2]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 06:46
Оценка:
PC>совместимости с C эта херь осталась (ЗЫ в С99 она тоже deprecated), в-четвертых
PC>понятней особенно для тех кто читает твой код(не этот).

С какой стати она deprecated, если в С void fun() и void fun(void) это разные вещи???
Of course, the code must be complete enough to compile and link.
Re[3]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 06:50
Оценка:
I>У меня почему-то обратная ассоциация была, что когда я пишу f(), то как бы использую пережиток из С в виде произвольного числа аргументов. Просмотрел Страуструпа, но не нашел советов на этот счет, хотя почему-то запомнилось что что-то было, видимо глюк в памяти. Будем считать, Вы меня убедили .

У тебя была правильная ассоциация с точки зрения С, а в С++ это функция без параметров.
Of course, the code must be complete enough to compile and link.
Re[3]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 06:54
Оценка:
"Lorenzo_LAMAS" <14979@users.rsdn.ru> wrote in message
news:1135351@news.rsdn.ru...
> С какой стати она deprecated, если в С void fun() и void fun(void) это разные
> вещи???
Там deprecated старое использование void fun() как fun(4, 23, 34, 23);

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[4]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 06:56
Оценка:
"Lorenzo_LAMAS" <14979@users.rsdn.ru> wrote in message
news:1135359@news.rsdn.ru...
> У тебя была правильная ассоциация с точки зрения С, а в С++ это функция без
> параметров.
Но ведь если программировать на С++, ты ведь со мной согласен ???


--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[4]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 06:56
Оценка:
PC>Там deprecated старое использование void fun() как fun(4, 23, 34, 23);
Черт, я в iso9899 даже секции deprecated пока не нашел
void fun();

int main()
{
   fun(1,2,3,4);
   return 0;
}

void fun(int, int, int, int)
{
}


Вот эта вот программа вполне ничего для компилятора C89/C99
Of course, the code must be complete enough to compile and link.
Re[5]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 06:58
Оценка:
PC>Но ведь если программировать на С++, ты ведь со мной согласен ???
Ээээ, что void fun() функция без параметров? Да, конечно.
Of course, the code must be complete enough to compile and link.
Re[6]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 07:00
Оценка:
"Lorenzo_LAMAS" <14979@users.rsdn.ru> wrote in message
news:1135375@news.rsdn.ru...
> PC>Но ведь если программировать на С++, ты ведь со мной согласен ???
> Ээээ, что void fun() функция без параметров? Да, конечно.
Что писать лучше void fun() чем void fun(void)

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[5]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 07:01
Оценка:
"Lorenzo_LAMAS" <14979@users.rsdn.ru> wrote in message
news:1135372@news.rsdn.ru...
> PC>Там deprecated старое использование void fun() как fun(4, 23, 34, 23);
Это не а стандарте это из best coding practices

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[7]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 07:02
Оценка:
PC>Что писать лучше void fun() чем void fun(void)
Да, естественно. Но я к этому и не придирался. Я не согласен только с утверждением, что void fun(void) — deprecated в С99/89

PC>--

PC>Pavel Chikulaev
Of course, the code must be complete enough to compile and link.
Re[8]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 07:04
Оценка:
"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
Posted via RSDN NNTP Server 1.9
Re[2]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:05
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>в-третьих (void) deprecated аж с 89

PC>года, но для сохранения обратной
PC>совместимости с C эта херь осталась (ЗЫ в С99 она тоже deprecated), в-четвертых
PC>понятней особенно для тех кто читает твой код(не этот).

'(void)' для объявления функций без параметров не является deprecated ни в С99, ни в С++ и никаких планов сделать его deprecated, AFAIK, нет.
Best regards,
Андрей Тарасевич
Re[8]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:08
Оценка:
Здравствуйте, 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>


I>Разве не так?


Здесь все правильно.
Best regards,
Андрей Тарасевич
Re[3]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 07:09
Оценка:
"Андрей Тарасевич" <2174@users.rsdn.ru> wrote in message
news:1135405@news.rsdn.ru...
> '(void)' для объявления функций без параметров не является deprecated ни в
> С99, ни в С++ и никаких планов сделать его deprecated, AFAIK, нет.
(void) не уберут никогда, просто писать в С++ так не рекомендуют, а в С99 —
использовать () как функцую с произвольным количеством параметров.

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[9]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:12
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

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, а по линии есть явный конструктор/нет явного конструктора. Но для данного примера это роли не играет.
Best regards,
Андрей Тарасевич
Re[10]: const и функции
От: Pavel Chikulaev Россия  
Дата: 21.04.05 07:16
Оценка:
AFAIK это только по отношению к new T/new T()


"Андрей Тарасевич" <2174@users.rsdn.ru> wrote in message
news:1135427@news.rsdn.ru...
> Неверно. 'A' в этом примере — POD-тип. Для POD типов инициализатор вида '()'
> не имеет никакого отношения ни к каким конструкторам. Такой инициализатор
> просто вызвает дефолтную инициализацию всех подобъектов класса 'A'. Т.е. будет
> выполнена дефолтная инициализация подобъекта типа 'int', а это именно
> обнуление.
>
> В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не
> по линии POD/не-POD, а по линии есть явный конструктор/нет явного
> конструктора. Но для данного примера это роли не играет.

--
Pavel Chikulaev
Posted via RSDN NNTP Server 1.9
Re[9]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:17
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

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' нет явного конструктора.
Best regards,
Андрей Тарасевич
Re[10]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:18
Оценка:
АТ>Здравствуйте, Вадим Никулин, Вы писали:

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 С++ обнуление будет даже в исходном варианте.
Best regards,
Андрей Тарасевич
Re[4]: const и функции
От: Шаталин Михаил  
Дата: 21.04.05 07:21
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

А>>Статическую функцию член класса ещё как можно создавать.

L_L>Речь шла о попытке объявить статическую функцию-член класса константной, чего сделать нельзя.

Извиняюсь, недопонял.
Re[14]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:27
Оценка:
Здравствуйте, 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.
Best regards,
Андрей Тарасевич
Re[11]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 07:32
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

>> Неверно. 'A' в этом примере — POD-тип. Для POD типов инициализатор вида '()'

>> не имеет никакого отношения ни к каким конструкторам. Такой инициализатор
>> просто вызвает дефолтную инициализацию всех подобъектов класса 'A'. Т.е. будет
>> выполнена дефолтная инициализация подобъекта типа 'int', а это именно
>> обнуление.
>>
>> В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не
>> по линии POD/не-POD, а по линии есть явный конструктор/нет явного
>> конструктора. Но для данного примера это роли не играет.

PC>AFAIK это только по отношению к new T/new T()


Нет. Это по отношению к всем местам в языке, где применим инициализатор вида '()'. Таких мест два: первое — это, как ты сказал, 'new T()', а второе — это выражения вида 'T()'.

Автор вопроса временно условно "ввел" третье место — объявление объекта вида 'T t();'. Именно в рамках этого условного введения я и рассуждал в своем ответе. Все мы прекрасно знаем, что это на самом деле не объявление объекта, но речь сейчас не о том.

(См. также коррекцию в моем следующем сообщении)
Best regards,
Андрей Тарасевич
Re[15]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 07:37
Оценка:
АТ>Не совсем точно. 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.
Re[16]: const и функции
От: Lorenzo_LAMAS  
Дата: 21.04.05 08:09
Оценка:
С другой стороны, думается мне, словосочетание "инициализатор вида" не подходит к такому

#include <iostream>

class A
{
public:
   virtual ~A(){}
   int i_;
};

int main()
{
   std::cout<<A().i_<<std::endl;
}
Of course, the code must be complete enough to compile and link.
Re[17]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 15:45
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

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>



Почему не подходит?
Best regards,
Андрей Тарасевич
Re[12]: const и функции
От: Андрей Тарасевич Беларусь  
Дата: 21.04.05 18:39
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

>>> В пост-TC1 стандарте языка для инициализатора '()' водораздел проходит уже не

>>> по линии POD/не-POD, а по линии есть явный конструктор/нет явного
>>> конструктора. Но для данного примера это роли не играет.

PC>>AFAIK это только по отношению к new T/new T()


АТ>Нет. Это по отношению к всем местам в языке, где применим инициализатор вида '()'. Таких мест два: первое — это, как ты сказал, 'new T()', а второе — это выражения вида 'T()'.


Есть еще третье место: инициализация поля класса в списке инициализаторов в конструкторе класса.
Best regards,
Андрей Тарасевич
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.