Встроенные типы данных по сравнению с пользовательскими типами данных в C ++ - PullRequest
2 голосов
/ 10 сентября 2011

Конструкторы строят объекты из пыли.

Это утверждение, с которым я неоднократно сталкивался в последнее время.

При инициализации встроенной переменной типа данныхпеременная также ДОЛЖНА быть «построена из пыли».Итак, существуют ли конструкторы для встроенных типов?

Кроме того, как компилятор по-разному обрабатывает класс BUILT IN DATATYPE и класс, определенный пользователем, при создании экземпляров для каждого из них?Я имею в виду детали относительно конструкторов, деструкторов и т. Д.

Этот запрос о переполнении стека относится к тому же самому, и в нем есть довольно интересные детали, наиболее интересным из которых является то, что сказал Бьярне ...!

У встроенных типов есть конструкторы по умолчанию?

Ответы [ 4 ]

5 голосов
/ 10 сентября 2011

Проще говоря, в соответствии со стандартом C ++:

12.1 Конструкторы [class.ctor]

2. Конструктор используется для инициализации объектов своего типа класса ...

так что нет, встроенные типы данных (если вы говорите о таких вещах, как int s и float s) не имеют конструкторов, потому что они не являются типами классов. Типы классов указываются так:

9 Классы [класс]

1. Класс - это тип. Его имя становится имя класса (9.1) в пределах его сфера применения.

        class-name:
                identifier
                template-id

Спецификаторы класса и используются разработанные спецификаторы типа (7.1.5.3) сделать имен классов . Объект класса состоит из (возможно пусто) последовательность членов и объектов базового класса.

        class-specifier:
                class-head { member-specification (opt) }

        class-head:
                class-key identifieropt base-clauseopt
                class-key nested-name-specifier identifier base-clauseopt
                class-key nested-name-specifieropt template-id base-clauseopt

        class-key:
                class
                struct
                union

И поскольку встроенные типы не объявляются таким образом, они не могут быть типами классов.

Так как создаются экземпляры встроенных типов? Общий процесс приведения в существование встроенных и классовых экземпляров называется initialization , для которого в стандарте C ++ (8.5) имеется огромный 8-страничный раздел, в котором изложены мучительные подробности об этом. Вот некоторые из правил , которые вы можете найти в разделе 8.5.

2 голосов
/ 10 сентября 2011

Как уже упоминалось, встроенные типы данных не имеют конструкторов.

Но вы все равно можете использовать синтаксис инициализации, подобный конструкции, как в int i(3) или int i = int(). Насколько я знаю, это было введено в язык для лучшей поддержки общего программирования, т. Е. Чтобы иметь возможность писать

template <class T>
T f() { T t = T(); }

f(42);
1 голос
/ 10 сентября 2011

При инициализации встроенной переменной типа данных переменная также ДОЛЖНА быть «построена из пыли». Итак, есть ли конструкторы для встроенных типов?

По запросу я перестраиваю свой ответ из пыли.

Мне не особенно нравится эта фраза "Конструкторы строят объекты из пыли". Это немного вводит в заблуждение.

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

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

int some_function (int some argument) {
  int index;
  ...
}

Обратите внимание, что index не было присвоено значение. При вводе в some_function часть памяти выделяется для переменной index. Эта память уже существует где-то; это просто отложено или выделено. Так как память где-то уже существует, каждый бит будет иметь какое-то ранее существующее значение. Если переменная не инициализирована, она будет иметь начальное значение. Начальное значение переменной index может быть 42, или 1404197501, или что-то совсем другое.

Некоторые языки обеспечивают инициализацию по умолчанию, если программист не указал ее. (C и C ++ этого не делают.) Иногда нет ничего плохого в том, чтобы не инициализировать переменную известным значением. Следующим оператором может быть, например, оператор присваивания. Преимущество инициализации по умолчанию состоит в том, что неудачная инициализация переменных является типичной ошибкой программирования. Недостатком является то, что эта инициализация имеет стоимость, хотя обычно крошечная. Эта крошечная стоимость может быть значительной, когда она происходит в цикле с множеством вложений, который критичен ко времени. Отсутствие начального значения по умолчанию соответствует философии C и C ++ - не предоставлять то, о чем программист не просил.

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

Некоторые классы имеют скрытые данные, которые абсолютно необходимо инициализировать. Некоторые классы имеют const или элементы справочных данных, которые абсолютно необходимо инициализировать. Эти классы должны быть инициализированы или созданы. Не все классы должны быть инициализированы. Класс или структура, которые не имеют каких-либо виртуальных функций, не имеют явно предоставленного конструктора или деструктора и все данные-члены которых являются простыми типами данных, называются обычными старыми данными или POD. Классы POD не нужно создавать.

Итог:

  • Объект, будь то примитивный тип или экземпляр очень сложного класса, не "построен из пыли". В конце концов, пыль очень вредна для компьютеров. Они построены из битов.
  • Установка или выделение памяти для какого-либо объекта и инициализация этой резервной памяти - две разные вещи.
  • В памяти нужно хранить объект, выделенный, а не созданный. Память уже существует. Поскольку эта память уже существует, биты, составляющие объект, будут иметь некоторые ранее существующие значения. Вы, конечно, никогда не должны полагаться на эти ранее существующие значения, но они есть.
  • Причина инициализации переменных или членов данных заключается в том, чтобы придать им достоверное, известное значение. Иногда такая инициализация - просто трата процессорного времени. Если вы не просили компилятор предоставить такое значение, C и C ++ предполагают, что упущение является преднамеренным.
  • Конструктор для некоторого объекта не выделяет память, необходимую для хранения самого объекта. Этот шаг уже был сделан к тому времени, когда вызывается конструктор. Что делает конструктор - это инициализирует уже выделенную память.

Первоначальный ответ:

Переменная типа примитива не обязательно должна быть "построена из пыли". Память для хранения переменной должна быть выделена, но переменную можно оставить неинициализированной. Конструктор не строит объект из пыли. Конструктор не выделяет память, необходимую для хранения создаваемого объекта. Эта память уже была выделена ко времени вызова конструктора. (Конструктор может инициализировать некоторый элемент данных указателя в память, выделенную конструктором, но биты, занятые этим указателем, уже должны существовать.)

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

Некоторые языки дают начальное значение каждой переменной. C и C ++ нет. Если вы не запрашивали начальное значение, C и C ++ не собираются принудительно устанавливать начальное значение для переменной. Эта инициализация имеет стоимость, обычно крошечную, но она существует.

0 голосов
/ 10 сентября 2011

Встроенные типы данных (фундаментальные типы, массивы, ссылки, указатели и перечисления) не имеют конструкторов.

Конструктор является функцией-членом. Функция-член может быть определена только для типа класса

C ++ 03 9,3 / 1:

"Функции, объявленные в определении класса, за исключением функций, объявленных с помощью спецификатора друга, называются функциями-членами этого класса".


Во многих случаях использование типа POD в определенных синтаксисах (приведенных ниже) может создать впечатление, что они создаются с использованием конструкторов или конструкторов копирования, но это просто инициализация без какого-либо из них.

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