Есть ли допустимый вариант использования, когда не-POD структура предпочтительнее класса? - PullRequest
0 голосов
/ 24 февраля 2012

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

Стандарт C ++ 2003, ISO 14882, раздел 9.0.4:

Структура - это определенный класссо структурой ключ-класс;его члены и базовые классы (раздел 10) являются общедоступными по умолчанию (раздел 11).Объединение - это класс, определенный с помощью объединения ключ-класс;по умолчанию его члены общедоступны, и он одновременно содержит только один элемент данных (9.5).[Примечание: агрегаты типа класса описаны в 8.5.1.] POD-структура - это агрегатный класс, который не имеет нестатических членов-данных типа non-POD-struct, non-POD-union (или массива таких типов) или ссылки, и не имеет пользовательского оператора назначения копирования ипользовательский деструктор отсутствует.Аналогично, POD-объединение - это совокупное объединение, которое не имеет нестатических членов-данных типа non-POD-struct, non-POD-union (или массива таких типов) или ссылки, и не имеет никакого пользовательского оператора назначения копирования и не имеетпользовательский деструктор.Класс POD - это класс, который является либо POD-структурой, либо POD-объединением.

Учитывая это определение, единственным дифференцирующим фактором между не-POD структурой и классом является модификатор доступа по умолчанию,

Вот то, что я мог бы себе представить как цель иметь структуры без POD:

  • Это устаревшая функция, которую необходимо поддерживать для обратной совместимости
  • Печатать public: сложно.

Наличие структур, не являющихся POD, может привести к боли, когда предполагается, что они являются POD другими системами, например, когда передаются на C и обратно.Чтобы проиллюстрировать, этот человек столкнулся с проблемами, когда структура, которая, как предполагалось, была POD, была обновлена ​​другим разработчиком так, что она больше не была POD .Поскольку POD-ness не устанавливается статически по умолчанию компилятором, приложение будет аварийно завершать работу во время выполнения, когда эта структура использовалась в контекстах, где можно использовать только структуры POD.Хуже того, я мог бы представить (хотя я точно не знаю, возможно ли это) структуру, не относящуюся к POD, которая работает в определенных обстоятельствах, требующих POD, и не работает в других, что приводит к ошибкам и сбоям, которые являются ничем иным, как труднымвыследить.

Видя, что существуют ситуации, когда наличие не-POD структур может привести к странному и нарушенному поведению, что такое использование не-POD структур?Почему структуры не проверяются статически на POD-ness во время компиляции (через std :: is_pod в C ++ 11 или в Boost-эквиваленте)?

Ответы [ 2 ]

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

Я думаю, что это бессмысленная историческая случайность, и, честно говоря, ключевое слово class вообще не должно было быть добавлено в C ++. О, хорошо!

Часто было бы неприятно, если бы struct требовалось быть POD - вы часто начинали с чего-то POD, называли бы это «структурой» только потому, что могли, а затем оказывались вынуждены изменить его в во многих местах позже, когда вы решите сделать его не POD.

Обратите внимание, что GCC (по крайней мере, до недавнего времени) было все равно, если вы (вперед) объявили что-то как класс в одном месте и как структуру в другом месте, или наоборот. Clang жалуется на подобные вещи (поскольку он имеет на это полное право, хотя это «нарушает» какой-то существующий код).

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

«POD-ness не устанавливается статически компилятором по умолчанию»

Oh?

#include <iostream>         // std::cout, std::endl
#include <type_traits>      // std::is_pod
#include <string>           // std::string, std::to_string
using namespace std;

struct A
{
    int x;
};

struct B
{
    string s;
};

int main()
{
    static bool const a = is_pod<A>::value;
    static_assert( a, "Ah..." );
    static_assert( !is_pod<B>::value, "Bah!" );
}

Причина, по которой struct разрешенобыть не POD, как, например, B выше, то есть , почему язык разработан таким образом , вероятно, можно найти в книге Бьярна Страуструпа «Дизайн и эволюция C ++».А если нет, то, вероятно, только сам Бьярне знает.Потому что эта общность C ++ в struct существует с самого начала.

...