Странные объекты класса поведения в объединении

Больше новинки, но это умно...

Лучшие 10 команд использовали:

$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head

Демонстрационный вывод:

 242 git
  83 rake
  43 cd
  33 ss
  24 ls
  15 rsg
  11 cap
  10 dig
   9 ping
   3 vi
5
задан Aza 10 April 2013 в 04:53
поделиться

3 ответа

В соответствии со стандартом C ++ (§9.5.1, цитируется также в других ответах):

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

Сначала я связался с статьей в Википедии о типах POD , в которой говорится:

A Тип POD в C ++ определяется либо как скалярный тип, либо как класс POD. Класс POD не имеет определяемого пользователем оператора присваивания копии, никакого определяемого пользователем деструктора, и никаких нестатических элементов данных, которые сами не являются POD. Более того, класс POD должен быть агрегированным, что означает, что он не имеет конструкторов, объявленных пользователем, частных или защищенных нестатических данных, баз и виртуальных функций. Стандарт включает утверждения о том, как POD должны вести себя в C ++.

и

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

Первое предложение второго абзаца может заставить вас думать, что C ++ позволяет только типам POD быть частью объединения. Это не совсем так, поскольку это позволяет классу с частными членами быть частью союза:

#include <iostream>
using namespace std;

class test1
{
  int i;
};

class test2
{
  int i;
};

union test
{
  test1 t1;
  test2 t2;
};

int main()
{
  cout << __is_pod(test1) << endl;
  cout << __is_pod(test2) << endl;
  cout << __is_pod(test) << endl;

  return 0;
}

Приведенная выше программа, скомпилированная с помощью MSVC ++, выводит:

0
0
1
16
ответ дан 18 December 2019 в 06:23
поделиться

Стандарт C ++ налагает определенные ограничения на типы данных, которые могут быть помещены в объединение. В 9.5.1 стандарт гласит:

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

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

6
ответ дан 18 December 2019 в 06:23
поделиться

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

3
ответ дан 18 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: