значения по умолчанию из не определенного конструктора - PullRequest
3 голосов
/ 18 февраля 2012

Бьярне писал: -
Для типа T T () является обозначением для значения по умолчанию, как определено конструктором по умолчанию . Что происходит, когда мы не объявляем конструктор по умолчанию? Например

using namespace std;

class date{
    int n,m;
    public:
   int day(){return n;}
   int month(){return m;}
          };//no default constructor

int main()
{
     date any =date();
     cout<<any.month()<<endl;   
     cout<<any.day()<<endl;
return 0;

}

Выход этой программы равен 0 и 0 при каждом запуске моей программы. Тогда я не объявлял никакого конструктора по умолчанию, почему существует значение по умолчанию, то есть 0?

Edit-

    class date{
        int n,m;
        public:
        date (){
        m=1;}
       int day(){return n;}
       int month(){return m;}
     };

 int main()
  {
     date any =date();
     cout<<any.month()<<endl;   
     cout<<any.day()<<endl;
return 0;

}

После прочтения ответов я предоставляю конструктор по умолчанию, но теперь n получает значение мусора, но согласно ответам оно должно быть 0, поскольку m вне досягаемости любого другого конструктора, и это инициализация значения, как указано в ответе

Ответы [ 3 ]

5 голосов
/ 18 февраля 2012

Поведение, которое вы видите, хорошо определено для вашего класса.


Как и почему поведение четко определено?

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

Согласно стандарту C ++ объект может быть инициализирован тремя способами:

  • Нулевая инициализация
  • Инициализация по умолчанию &
  • Значение Инициализация

Когда за именем типа или инициализатором конструктора следует (), инициализация происходит посредством инициализации значения.

Таким образом,

date any =date();
              ^^^

Значение Инициализирует безымянный объект и затем копирует его в локальный объект any, пока:

date any;

будет Инициализация по умолчанию .

Значение Initialization дает начальное значение ноль для членов, которые находятся вне досягаемости любого конструктора.
В вашей программе n и m недоступны для любого конструктора и, следовательно, инициализируются как 0.


Ответ на отредактированный вопрос:
В вашем отредактированном случае ваш класс предоставляет конструктор без аргументов date(), который способен (и должен) инициализировать элементы n и m, но этот конструктор не инициализирует оба члена, поэтому в этом случае нет Происходит нулевая инициализация, и неинициализированные элементы в объекте имеют значение Indeterminate (любое случайное), далее этот временный объект копируется в объект any, который отображает показанные неопределенные значения элементов.


Для фанатов Standerdese:
Правила для инициализации объекта точно определены в:

C ++ 03 Стандарт 8.5 / 5:

К инициализации нулями объект типа T означает:
- если T - скалярный тип (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;
- если T является типом класса, не являющимся объединением, каждый элемент нестатических данных и каждый подобъект базового класса инициализируются нулями;
- если T является типом объединения, первый именованный элемент данных объекта инициализируется нулями;
- если T является типом массива, каждый элемент инициализируется нулями;
- если T является ссылочным типом, инициализация не выполняется.

К default-initialize объект типа T означает:
- если T является типом класса, отличным от POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация является некорректной, если у T нет доступного конструктора по умолчанию);
- если T является типом массива, каждый элемент инициализируется по умолчанию;
- иначе объект инициализируется нулями.

К значение-инициализация объект типа T означает:
- если T является типом класса (раздел 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса T инициализируется значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- иначе объект инициализируется нулями

4 голосов
/ 18 февраля 2012

Поскольку компилятор, ругаясь под нос, генерирует его для вас.

РЕДАКТИРОВАТЬ: Поскольку Алс сказал, что он не отвечает на вопрос, я уточню.Когда вы используете date any = date();, вы вызываете сгенерированный компилятором конструктор по умолчанию.Этот конструктор вызывает конструкторы по умолчанию для всех базовых классов и членов данных.Для ваших членов данных int конструктор по умолчанию - int(), который устанавливает значение 0.Вот код на ideone.com

#include <iostream>

int main( void )
{
 int i = -123;

 i = int(); 

 std::cout << i << std::endl; 


 return( 0 );
}

Вывод программы:

0
0 голосов
/ 18 февраля 2012

Из проекта стандарта C ++ (рабочий документ за декабрь 1996 года):

Если для класса X нет объявленного пользователем конструктора, конструктор по умолчанию объявляется неявно. Неявно объявленный конструктор по умолчанию является встроенным открытым членом своего класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...