почему конструктор по умолчанию отсутствует для класса, содержащего константные элементы данных

почему конструктор по умолчанию не добавляется компилятором для класса, содержащего постоянные члены данных. см. приведенный ниже код, в котором я объявил постоянный элемент данных «a», и при попытке создать объект для класса «ClassA» он говорит, что нет подходящего конструктора по умолчанию. пожалуйста помоги.

#include "stdafx.h"
#include <iostream>
using namespace std;

class ClassA
{
    private:
  const int a;
    public :
  void print()
  {
      cout << "hello world" << endl;
  }
};

int main()
{
  ClassA obj;
  obj.print();
  return 0;
}

person nagaradderKantesh    schedule 23.05.2013    source источник
comment
Вы должны инициализировать a.   -  person chris    schedule 23.05.2013
comment
Несмотря на комментарии в других местах, очевидная инициализация для a выполняется с помощью инициализатора по умолчанию, а именно int(), который будет инициализирован нулем. Да, это (почти) бессмысленно, но есть ли у кого-нибудь ссылка на то, почему это невозможно для конструктора по умолчанию?   -  person Keith    schedule 23.05.2013
comment
@Keith Это просто выбор языка. Встроенные элементы данных не инициализируются по умолчанию.   -  person juanchopanza    schedule 23.05.2013
comment
@juanchopanza. Конечно. Так почему проблема с отсутствием инициализации возникает только потому, что a есть const?   -  person Keith    schedule 23.05.2013
comment
Это было решено в C#, заставив компилятор заставить разработчика инициализировать const переменные в строке.   -  person Ken D    schedule 23.05.2013
comment
@Keith: потому что вы не можете изменить значение переменной const постфактум, так что в этом хорошего, если она не инициализирована для начала? (зная, что чтение неинициализированного значения является поведением undefined)   -  person Matthieu M.    schedule 23.05.2013
comment
@Keith Что сказал Матье М.. Но это другое языковое решение. Это можно было бы разрешить, но тогда вы получили бы элемент данных с неопределенным значением, которое нельзя изменить. Маловероятно, что это может быть полезно, так как это легко приведет к неопределенному поведению (кстати, я задал тот же вопрос несколько лет назад. Тогда это был дубликат, но я не могу его найти...)   -  person juanchopanza    schedule 23.05.2013
comment
@MatthieuM. Чарльз Бейли отвечает с точки зрения стандарта; так дело закрыто. Однако я не думаю, что сбой инициализации конструктора означает, что a является неинициализированной памятью; не могли бы мы наложить известную память, используя новую на месте?   -  person Keith    schedule 24.05.2013


Ответы (5)


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

person aaronman    schedule 23.05.2013

Правило C++03 было указано в 12.6.2/4 [class.base.init]. Если нестатический член класса не был упомянут в списке инициализаторов членов конструктора, тогда, если он был квалифицирован const, он должен был бы относиться к типу класса, отличному от POD, с конструктором, объявленным пользователем, иначе программа будет неработоспособной. -сформированный. Неявно определенный конструктор определяется с пустым списком инициализаторов членов (и пустым телом), поэтому в этом случае неявное определение неявно объявленного конструктора по умолчанию также приведет к неправильному формату программы.

Правило С++ 11 означает то же самое. Нестатические элементы данных, не указанные в списке инициализаторов элементов, инициализируются по умолчанию. В C++11 8.5/6 [dcl.init], "[...] Если программа вызывает инициализацию по умолчанию объекта константного типа T, T должен быть типом класса с предоставленным пользователем конструктор по умолчанию." что сводится к тому же правилу в этом случае.

person CB Bailey    schedule 23.05.2013

Поскольку a является переменной const, вы можете объявить ее статической и инициализировать без использования конструктора следующим образом:

class ClassA
{
    private:
    const static int a=10;
    public :
    void print()
    {
      cout << "hello world" << endl;
    }
};

int main()
{
  ClassA obj;
  obj.print();
  return 0;
}
person Deepu    schedule 23.05.2013

Тип int не имеет значения по умолчанию в C или C++, поэтому значение a будет неопределенным. Например, VC++ заполнит значение a другим значением по умолчанию, если он запускается в режиме отладки, и если он запускается в режиме выпуска.

При отладке VC++ заполняет неинициализированную память следующими значениями:

  • 0xCCCCCCCC — используется библиотекой времени выполнения отладки Microsoft C++ и многими средами DOS для обозначения неинициализированной памяти стека.
  • 0xCDCDCDCD — используется отладочной функцией malloc() Microsoft C/C++ для пометки неинициализированной памяти кучи, обычно возвращаемой функцией HeapAlloc().

Поэтому, не инициализируя a, ваша программа каждый раз будет иметь другое значение const.

person Steve    schedule 23.05.2013

Я считаю, что вы должны явно инициализировать константные члены в конструкторе, вам нужно будет их где-то установить, и, поскольку они константны, вы можете просто установить их где угодно!

person matt    schedule 23.05.2013