Это относится не только к C ++, но и к любому языку, который предоставляет как структуры, так и классы.
Джейсон Бантинг
3
Я все еще не согласен - я подхожу к этому вопросу семантически. Возможно, есть некоторые технические различия, но семантически они не являются. Структуры действительно полезны для создания типов значений, а классы - нет.
Джейсон Бантинг
4
Я считаю, что нет серьезных причин для использования структур в C ++. Для меня структуры - это еще одна избыточная «особенность» C ++, которая существует только для совместимости с C, например typedefs. Они не существовали бы, если бы C ++ изначально не рассматривался как расширение C, а был разработан с нуля, например, Java. В целом, я считаю, что многие из самых странных вещей в C ++ связаны с совместимостью с Си.
Костас
5
Структура - для POD (простых старых данных) и всех членов доступность общедоступна. Класс - когда вам нужна лучшая инкапсуляция и нужны функции-члены для работы с состоянием класса.
Navaneeth KN
4
Это верно только по соглашению. Разницы нет, кроме инкапсуляции по умолчанию.
Дэйв Хиллиер
Ответы:
807
Различия между a classи a structв C ++ заключаются в том, что структуры имеют publicэлементы по умолчанию и базы, а классы имеют privateэлементы и базы по умолчанию . И классы, и структуры могут иметь смесь public, protectedа privateчлены могут использовать наследование и могут иметь функции-члены.
Я бы порекомендовал использовать структуры в качестве простых структур старых данных без каких-либо классоподобных функций и использовать классы в качестве совокупных структур privateданных с данными и функциями-членами.
Структура без модификаторов или методов называется структурой POD, которая существует как обратно совместимый интерфейс с библиотеками C, поскольку (предположительно) она гарантированно будет размещена так, как если бы она была структурой C. Помимо этого единственного исключения, тем не менее, единственная разница, как указано.
workmad3
26
@ workmad3: имя вводит в заблуждение, но 9/4 (C ++ 03) гласит: «POD-структура - это агрегатный класс, который не имеет нестатических членов-данных типа non-POD-struct, non-POD-union (или массив таких типов) или ссылка, и не имеет никакого пользовательского оператора назначения копирования и никакого пользовательского деструктора. " Нет никаких ограничений на использование класса-ключа "struct" и никаких ограничений на использование "public" (см. 8.5.1 / 1 для совокупных требований). Это не разница между "структура" и "класс".
5
Использование вами «агрегата» может быть неправильно понято, учитывая определение стандарта. :)
3
Согласно книге Страуструпа «Принципы и практика»: «структуры должны в первую очередь использоваться там, где члены могут принимать любое значение» (т.
Е. Там,
6
Конечно, вы можете использовать классы при взаимодействии с C. Нет никакой разницы между классами и структурами. Структуры являются классами; только доступ по умолчанию переключается с частного на публичный.
Себастьян Мах
230
Как все остальные отмечают, на самом деле есть только два фактических языковых различия:
structпо умолчанию общедоступный доступ и по classумолчанию частный доступ.
При наследовании по structумолчанию publicнаследуется и по classумолчанию privateнаследуется. (По иронии судьбы, как и во многих других вещах в C ++, по умолчанию задом наперед: publicнаследование является гораздо более распространенным выбором, но люди редко объявляют structs просто для экономии при вводе publicключевого слова " ".
Но реальное различие на практике между class/, structкоторый объявляет конструктор / деструктор, и тем, который не делает. Существуют определенные гарантии для типа POD «обычные старые данные», которые больше не применяются, когда вы берете на себя конструкцию класса. Чтобы сохранить это различие, многие люди сознательно используют structs только для типов POD, и, если они вообще собираются добавлять какие-либо методы, используют classes. Разница между двумя фрагментами ниже бессмысленна:
class X
{public:// ...};struct X
{// ...};
(Кстати, вот поток с некоторыми хорошими объяснениями о том, что на самом деле означает «тип POD»: что такое типы POD в C ++? )
Хороший пример относительно наследственных различий: здесь .
Лиран Ореви
8
Используете ли вы structили classне имеете никакого отношения к тому, является ли ваш объект POD или вам нужно определить конструктор / деструктор копирования. Функции-члены также не имеют отношения к POD. Когда я перечитываю то, что вы написали, я вижу, что вы не предлагаете иначе, но нынешняя формулировка сбивает с толку
Дэвид Стоун
1
@DavidStone По сути, предполагается, что POD-структуры гарантированно обратно совместимы с C-кодом, и, следовательно, в основном предполагается, что они просто спроектированы как C-style-структуры.
Джастин Тайм - Восстановить Монику
3
Часть «реального различия» этого ответа совершенно неверна.
Да, вам, возможно, придется изменить свои ключевые слова, изменяющие доступ, внутри определения класса, в зависимости от того, какое ключевое слово вы использовали для объявления класса.
Но, помимо синтаксиса, единственной причиной выбора одного из них является соглашение / стиль / предпочтение.
Некоторые люди предпочитают придерживаться structключевого слова для классов без функций-членов, потому что полученное определение «выглядит как» простая структура из C.
Точно так же некоторым людям нравится использовать classключевое слово для классов с функциями-членами и privateданными, потому что оно говорит «класс» и поэтому выглядит как примеры из их любимой книги по объектно-ориентированному программированию.
Реальность такова, что это полностью зависит от вас и вашей команды, и это в буквальном смысле не будет иметь никакого значения для вашей программы.
Следующие два класса абсолютно эквивалентны во всех отношениях, кроме их имени:
structFoo{int x;};classBar{public:int x;};
Вы даже можете переключать ключевые слова при повторном выделении:
Обратите внимание, что вы не можете переключать ключевые слова при переопределении ; это только потому, что (согласно правилу одного определения) повторяющиеся определения классов в единицах перевода должны «состоять из одной и той же последовательности токенов» . Это означает , что вы не можете даже обмениваться const int member;с int const member;, и не имеет ничего общего с семантикой classили struct.
Это было очень информативно, и, честно говоря, мой любимый ответ. Все остальные относятся к ним как к отдельным сущностям, когда под капотом они одинаковы. Интересно, считается ли определение структуры в среде Arduino классом cpp, поскольку он скомпилирован с использованием g ++.
Бенджамин
4
@Ben Конечно, это так. Компилятор Arduino компилирует C ++; это конец.
underscore_d
7
Так что, если я правильно понимаю: пока ваши модификаторы видимости явные, а не опущены, это не имеет значения. Вы можете написать огромное приложение на C ++, используя только структуры; или вы могли бы пройти и изменить каждый случай структуры на класс. Пока вы не используете видимость по умолчанию, приложения будут точно такими же.
Райан Ланди
Я не уверен, что одна единица перевода программы на C ++ может иметь полное объявление, class foo { public: ... };а другая - иметь, struct foo { ... };что должно было бы выполняться в соответствии с «абсолютно эквивалентным» утверждением. Дело в том, что неполные декларации struct foo;и class foo;взаимозаменяемы. Они не определяют тело класса и поэтому ничего не говорят о макете доступа.
Kaz
@Kaz: Вы правы - если определения были для буквально одного типа, они должны быть лексически идентичными, чтобы поведение было четко определено. Структура ключ и класс-ключ иным образом логически сменный , хотя (где семантика не влияет), а также Fooи Barпо - прежнему эквивалентны / одинаковые типы. Я обязательно сказал «при повторном выделении текста » и привел пример. Если подумать, я уточню это в ответе, чтобы не вводить людей в заблуждение в UB
Гонки
54
Единственный раз, когда я использую структуру вместо класса, это когда объявляю функтор непосредственно перед его использованием в вызове функции и хочу свести к минимуму синтаксис для ясности. например:
Члены и базовые классы структуры являются открытыми по умолчанию, в то время как в классе они по умолчанию являются закрытыми. Примечание: вы должны сделать ваши базовые классы явно общедоступными, закрытыми или защищенными, а не полагаться на значения по умолчанию.
Структура и класс в остальном функционально эквивалентны.
Ладно, хватит этого скрипучего чистого техно разговора. Эмоционально большинство разработчиков проводят четкое различие между классом и структурой. Структура просто ощущается как открытая куча битов с очень небольшим количеством способов инкапсуляции или функциональности. Класс чувствует себя живым и ответственным членом общества с интеллектуальными услугами, сильным барьером инкапсуляции и четко определенным интерфейсом. Так как это значение имеет большинство людей, вам, вероятно, следует использовать ключевое слово struct, если у вас есть класс, у которого очень мало методов и открытых данных (такие вещи существуют в хорошо спроектированных системах!), Но в противном случае вам, вероятно, следует использовать класс ключевое слово.
Я не понимаю, почему они утверждают, что структура и класс функционально одинаковы, но говорят, что в некоторых случаях они предпочитают одно другому другому без каких-либо рассуждений ..
deetz
3
Причина в соглашении. Компилятору все равно, какой вы используете, но другому разработчику, изучающему ваш код, будет легче понять, что вы имели в виду.
Тал Прессман
3
@deetz: весь третий абзац рассуждений.
Гонки
Вау, пришедший из «старой школы», я понятия не имел, что структура может иметь методы и даже наследование. Я всегда использовал struct для использования только данных без каких-либо методов, и обычно при работе с кодом API требуется структура. Могут ли структуры поддерживать множественное наследование?
Пол Маккарти
21
Одно из мест, где структура была полезна для меня, - это когда у меня есть система, которая получает сообщения фиксированного формата (скажем, последовательный порт) из другой системы. Вы можете преобразовать поток байтов в структуру, которая определяет ваши поля, а затем легко получить доступ к полям.
Очевидно, это то же самое, что вы сделали бы в C, но я обнаружил, что накладные расходы, связанные с декодированием сообщения в класс, обычно не стоят того.
Или вы можете просто реализовать operator >>класс вместо написания processMessageфункции, которая сделает ваш C ++ более похожим на правильный C ++ и менее похожим на C.
Ник Бастин,
1
Помимо того, что он не переносим между различными системами, это нарушает правила псевдонимов, поэтому не гарантируется работа даже в пределах одной архитектуры.
underscore_d
@underscore_d Это может работать независимо от платформы (но не от компилятора), но вы должны использовать фиксированные битовые поля, __packed__структуру и иметь реализацию ifdef с поддержкой порядка байтов (вам нужно перевернуть порядок на машине, где порядок байтов противоположен внешнему источнику данных обеспечивает). Это не красиво, но я использовал для упаковки / распаковки регистров для удаленных периферийных устройств на встроенных платформах портативным способом.
авария
1
@jacwah Да, хорошо. Псевдоним не будет проблемой здесь, потому что один из указателей является charтипом, который освобожден от псевдонимов. Тем не менее, есть проблема, хотя и другая: приведение char*к другому типу, если на самом деле не было ни одного объекта последнего типа, уже инициализированного по этому адресу, является UB, поскольку оно нарушает правила жизни. Afaik, даже если тип назначения тривиально конструируем, просто выделение памяти недостаточно для C ++, чтобы формально разрешить обрабатывать эту память как этот тип.
underscore_d
19
Вы можете использовать "struct" в C ++, если вы пишете библиотеку, внутренняя часть которой - C ++, но API может вызываться из кода C или C ++. Вы просто создаете один заголовок, который содержит структуры и глобальные функции API, которые вы открываете как для C, так и для C ++ кода:
// C access Header to a C++ library#ifdef __cpp
extern"C"{#endif// Put your C struct's herestruct foo
{...};// NOTE: the typedef is used because C does not automatically generate// a typedef with the same name as a struct like C++.typedefstruct foo foo;// Put your C API functions herevoid bar(foo *fun);#ifdef __cpp
}#endif
Затем вы можете написать функцию bar () в файле C ++, используя код C ++, и сделать его вызываемым из C, и эти два мира смогут обмениваться данными через объявленные структуры. Конечно, при смешивании C и C ++ есть и другие предостережения, но это упрощенный пример.
Лучший подходящий ответ. C-совместимость - действительно самая важная причина. все остальные вещи, такие как доступ по умолчанию, являются эзотерическими.
Валентин Хайниц
16
Как говорят все, единственная реальная разница - доступ по умолчанию. Но я особенно использую struct, когда я не хочу никакой инкапсуляции с простым классом данных, даже если я реализую некоторые вспомогательные методы. Например, когда мне нужно что-то вроде этого:
+1 за пример структуры с некоторыми функциями-членами, которые не чувствуют, что вы «убрали структуру».
einpoklum
9
Чтобы ответить на мой собственный вопрос (бессовестно), как уже упоминалось, привилегии доступа - единственное различие между ними в C ++.
Я склонен использовать структуру только для хранения данных. Я позволю ему получить несколько вспомогательных функций, если это облегчит работу с данными. Однако, как только данные требуют управления потоком (т. Е. Методы получения / установки, которые поддерживают или защищают внутреннее состояние) или начинают получать какие-либо основные функциональные возможности (в основном более объектоподобные), они будут «обновлены» до класса, чтобы лучше передавать намерения.
Структуры ( общем случае POD ) удобны, когда вы предоставляете C-совместимый интерфейс с реализацией C ++, поскольку они переносимы через границы языка и форматы компоновщика.
Если это вас не касается, тогда я полагаю, что использование «struct» вместо «class» является хорошим средством передачи намерений (как сказано выше в @ZeroSignal). Структуры также имеют более предсказуемую семантику копирования, поэтому они полезны для данных, которые вы собираетесь записывать на внешний носитель или передавать по проводам.
Структуры также удобны для различных задач метапрограммирования, таких как шаблоны признаков, которые просто предоставляют набор зависимых типов:
template<typename T>struct type_traits {typedef T type;typedef T::iterator_type iterator_type;...};
... Но это на самом деле просто использование общедоступного уровня защиты struct по умолчанию ...
Это не правильное использование POD. Структура (или класс) может быть структурой POD, если (и только если) она содержит ТОЛЬКО членов POD.
Мартин Йорк,
4
«Предсказуемая семантика копирования». Симантика такая же, как и для класса (и имеют те же проблемы (мелкое копирование)).
Мартин Йорк,
2
Этот пост заставит вас поверить (надеюсь, случайно), что все структуры - это PODы. Это совсем не так. Я надеюсь, что люди не вводят в заблуждение этим.
Майкл Дорст
8
Для C ++ между структурами и классами нет большой разницы. Основное функциональное отличие состоит в том, что члены структуры являются открытыми по умолчанию, в то время как они являются закрытыми по умолчанию в классах. В остальном, что касается языка, они эквивалентны.
Тем не менее, я склонен использовать структуры в C ++, как и в C #, подобно тому, что сказал Брайан. Структуры - это простые контейнеры данных, в то время как классы используются для объектов, которые должны воздействовать на данные в дополнение к их удержанию.
Они в значительной степени одно и то же. Благодаря магии C ++, структура может содержать функции, использовать наследование, создаваться с использованием «new» и так далее, как класс
Единственное функциональное отличие состоит в том, что класс начинается с прав частного доступа, а структура начинается с открытого. Это поддерживать обратную совместимость с C.
На практике я всегда использовал структуры как носители данных, а классы - как объекты.
Тем не менее, имейте в виду, что не стоит отправлять декларацию. как класс ( class X;) и определить его как struct ( struct X { ... }). Он может работать на некоторых линкерах (например, g ++) и может не работать на других (например, MSVC), так что вы окажетесь в аду разработчиков.
@LightnessRacesinOrbit Я не могу, к сожалению. Я даже не могу создать пример. Тривиальный class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }не только компилируется и запускается с MSVC 2017, он даже производит четкое предупреждение, которое Fooбыло объявлено как, structно определено как class. Но я также хорошо помню, что нашей команде понадобилось полдня, чтобы найти эту глупую ошибку. Я не уверен, какую версию MSVC мы использовали тогда.
Пасби
Линкер не должен даже знать о том, использовали ли вы classили structв предварительном объявлении, и эти два свободно взаимозаменяемы в соответствии со стандартом (хотя известно, что VS предупреждает; я всегда предполагал, что это просто для того, чтобы избежать явных ошибок программиста). Здесь что-то не пахнет. Вы уверены, что это не была ошибка нарушения ODR?
Я точно не помню. Проблема возникла не непосредственно в приложении, а в библиотеке, которая использовалась в gtest. Я просто знаю, что компоновщик выдал непонятные ошибки (LNK ???). Как только я заменил « structвперед» на « classвперед», проблемы исчезли. На сегодняшний день я тоже нахожу это странным. Я был бы рад, если бы вы могли пролить свет на это.
пасби
3
Учебный класс.
Члены класса по умолчанию закрыты.
class test_one {int main_one();};
Эквивалентно
class test_one {private:int main_one();};
Так что если вы попробуете
int two = one.main_one();
Мы получим ошибку: main_one is privateпотому что это не доступно. Мы можем решить это, инициализировав его, указав его как общедоступный, т.е.
class test_one {public:int main_one();};
Struct.
Структура - это класс, члены которого по умолчанию являются публичными.
struct test_one {int main_one;};
Значит main_oneчастное т.е.
class test_one {public:int main_one;};
Я использую структуры для структур данных, где члены могут принимать любое значение, так проще.
Преимущество по structсравнению с этим classзаключается в том, что он сохраняет одну строку кода, если придерживается «сначала общедоступных членов, затем частных». В этом свете я нахожу ключевое слово classбесполезным.
Вот еще одна причина использовать только structи никогда class. В некоторых рекомендациях по стилю кода для C ++ предлагается использовать строчные буквы для макросов функций. Обоснование заключается в том, что при преобразовании макроса во встроенную функцию имя менять не нужно. Тоже самое. У вас есть хорошая структура в стиле C и однажды вы обнаружите, что вам нужно добавить конструктор или какой-нибудь удобный метод. Вы меняете это на class? Где угодно?
Различение между structs и classes - это слишком много хлопот, мешающих делать то, что мы должны делать - программирование. Как и многие из проблем C ++, он возникает из-за сильного желания обратной совместимости.
Зачем вам нужно изменить его на class? Вы думаете, что класс, определенный с помощью structключевого слова, не может иметь функции-члены или конструктор?
Гонки
@LightnessRacesinOrbit из-за 1. согласованности и 2. некоторые статические анализаторы жалуются на нарушение 1.
Ворак
Это не следует Каких других «последовательностей» вы придерживаетесь? Каждый класс с членом joe()должен быть определен с classключевым словом? Каждый класс по крайней мере с 4 intчленами должен быть определен с structключевым словом?
Гонки
@LightnessRacesinOrbit Я имею в виду идиому «агрегаты POD определены с помощью structагрегатов с методами class». Слишком много хлопот.
Vorac
2
они одинаковы с разными значениями по умолчанию (частными по умолчанию для classи публичными по умолчанию для struct), поэтому теоретически они полностью взаимозаменяемы.
поэтому, если я просто хочу упаковать некоторую информацию для перемещения, я использую структуру, даже если я поместил там несколько методов (но не много). Если это в основном непрозрачная вещь, где основное использование будет через методы, а не напрямую членам данных, я использую полный класс.
Структуры по умолчанию имеют открытый доступ, а классы по умолчанию имеют частный доступ.
Лично я использую структуры для объектов передачи данных или как объекты значений. Когда используется как таковой, я объявляю все члены как const, чтобы предотвратить изменение другим кодом.
Оба , structи classодин и те же под капотом , хотя с различным по умолчанию как для видимости, по structумолчанию является публичным и по classумолчанию является частным. Вы можете изменить одно на другое с соответствующим использованием privateи public. Они оба допускают наследование, методы, конструкторы, деструкторы и все остальные полезности объектно-ориентированного языка.
Однако одно огромное различие между ними заключается в том, structчто ключевое слово поддерживается в C, а classнет. Это означает , что один можно использовать structв включаемый файл , который может быть #includeв любой C ++ или C до тех пор , как structэто обычный стиль C structи все остальное в инклюднике совместим с C, то есть не C ++ конкретные ключевые слова , такие как private, public, нет методы, без наследования и т. д. и т. д. и т. п.
Стиль AC structможет использоваться с другими интерфейсами, которые поддерживают использование стиля C structдля передачи данных назад и вперед по интерфейсу.
Стиль AC struct- это своего рода шаблон (не шаблон C ++, а шаблон или трафарет), который описывает макет области памяти. На протяжении многих лет интерфейсы пригодными для использования C и C плагинов (здесь смотрит на вас Java и Python и Visual Basic) были созданы некоторые из которых работают в стиле C struct.
Технически оба они одинаковы в C ++ - например, структура может иметь перегруженные операторы и т. Д.
Однако :
Я использую структуры, когда я хочу передавать информацию нескольких типов одновременно, я использую классы, когда я имею дело с «функциональным» объектом.
Когда вы решите использовать struct и когда использовать класс в C ++?
Я использую, structкогда я определяю functorsи POD. В противном случае я использую class.
// '()' is public by default!struct mycompare :public std::binary_function<int,int,bool>{booloperator()(int first,int second){return first < second;}};class mycompare :public std::binary_function<int,int,bool>{public:booloperator()(int first,int second){return first < second;}};
Все члены класса по умолчанию закрыты, а все члены структуры по умолчанию общедоступны. Класс имеет частные базы по умолчанию, а Struct имеет открытые базы по умолчанию. Struct в случае C не может иметь функции-члены, тогда как в случае C ++ мы можем добавить функции-члены в структуру. Кроме этих различий, я не нахожу в них ничего удивительного.
Я использую struct только тогда, когда мне нужно хранить некоторые данные без каких-либо связанных с ними функций-членов (для работы с данными-членами) и для прямого доступа к переменным данных.
Например: чтение / запись данных из файлов и потоков сокетов и т. Д. Передача аргументов функции в структуре, где аргументов функции слишком много и синтаксис функции выглядит слишком длинным.
Технически между классом и struture нет большой разницы, кроме доступности по умолчанию. Более того, от стиля программирования зависит, как вы его используете.
Я думал, что Structs был задуман как структура данных (например, массив данных с несколькими типами данных), а классы были предназначены для упаковки кода (например, коллекции подпрограмм и функций).
Я не могу представить себе сценарий, в котором вы будете использовать структуру, когда вам нужны частные члены, если вы не пытаетесь вводить в заблуждение.
Кажется, что использование структур - это скорее синтаксическая индикация того, как будут использоваться данные, но я бы предпочел просто создать класс и попытаться сделать это явным в названии класса или в комментариях.
По моему мнению, «синтаксическая индикация того, как будут использоваться данные», является вполне веской причиной для использования структуры, особенно если альтернативой является использование комментария или имени в имени класса.
Виктор Шер
2
Разве объявление о structтом, что члены класса будут по умолчанию открытыми, не будет уже довольно явным?
Ответы:
Различия между a
class
и astruct
в C ++ заключаются в том, что структуры имеютpublic
элементы по умолчанию и базы, а классы имеютprivate
элементы и базы по умолчанию . И классы, и структуры могут иметь смесьpublic
,protected
аprivate
члены могут использовать наследование и могут иметь функции-члены.Я бы порекомендовал использовать структуры в качестве простых структур старых данных без каких-либо классоподобных функций и использовать классы в качестве совокупных структур
private
данных с данными и функциями-членами.источник
Как все остальные отмечают, на самом деле есть только два фактических языковых различия:
struct
по умолчанию общедоступный доступ и поclass
умолчанию частный доступ.struct
умолчаниюpublic
наследуется и поclass
умолчаниюprivate
наследуется. (По иронии судьбы, как и во многих других вещах в C ++, по умолчанию задом наперед:public
наследование является гораздо более распространенным выбором, но люди редко объявляютstruct
s просто для экономии при вводеpublic
ключевого слова " ".Но реальное различие на практике между
class
/,struct
который объявляет конструктор / деструктор, и тем, который не делает. Существуют определенные гарантии для типа POD «обычные старые данные», которые больше не применяются, когда вы берете на себя конструкцию класса. Чтобы сохранить это различие, многие люди сознательно используютstruct
s только для типов POD, и, если они вообще собираются добавлять какие-либо методы, используютclass
es. Разница между двумя фрагментами ниже бессмысленна:(Кстати, вот поток с некоторыми хорошими объяснениями о том, что на самом деле означает «тип POD»: что такое типы POD в C ++? )
источник
struct
илиclass
не имеете никакого отношения к тому, является ли ваш объект POD или вам нужно определить конструктор / деструктор копирования. Функции-члены также не имеют отношения к POD. Когда я перечитываю то, что вы написали, я вижу, что вы не предлагаете иначе, но нынешняя формулировка сбивает с толкуЕсть много заблуждений в существующих ответах.
Оба
class
иstruct
объявляют класс.Да, вам, возможно, придется изменить свои ключевые слова, изменяющие доступ, внутри определения класса, в зависимости от того, какое ключевое слово вы использовали для объявления класса.
Но, помимо синтаксиса, единственной причиной выбора одного из них является соглашение / стиль / предпочтение.
Некоторые люди предпочитают придерживаться
struct
ключевого слова для классов без функций-членов, потому что полученное определение «выглядит как» простая структура из C.Точно так же некоторым людям нравится использовать
class
ключевое слово для классов с функциями-членами иprivate
данными, потому что оно говорит «класс» и поэтому выглядит как примеры из их любимой книги по объектно-ориентированному программированию.Реальность такова, что это полностью зависит от вас и вашей команды, и это в буквальном смысле не будет иметь никакого значения для вашей программы.
Следующие два класса абсолютно эквивалентны во всех отношениях, кроме их имени:
Вы даже можете переключать ключевые слова при повторном выделении:
(хотя это нарушает сборки Visual Studio из-за несоответствия, поэтому компилятор выдаст предупреждение, когда вы сделаете это.)
и следующие выражения оба оценивают как истинные:
Обратите внимание, что вы не можете переключать ключевые слова при переопределении ; это только потому, что (согласно правилу одного определения) повторяющиеся определения классов в единицах перевода должны «состоять из одной и той же последовательности токенов» . Это означает , что вы не можете даже обмениваться
const int member;
сint const member;
, и не имеет ничего общего с семантикойclass
илиstruct
.источник
class foo { public: ... };
а другая - иметь,struct foo { ... };
что должно было бы выполняться в соответствии с «абсолютно эквивалентным» утверждением. Дело в том, что неполные декларацииstruct foo;
иclass foo;
взаимозаменяемы. Они не определяют тело класса и поэтому ничего не говорят о макете доступа.Foo
иBar
по - прежнему эквивалентны / одинаковые типы. Я обязательно сказал «при повторном выделении текста » и привел пример. Если подумать, я уточню это в ответе, чтобы не вводить людей в заблуждение в UBЕдинственный раз, когда я использую структуру вместо класса, это когда объявляю функтор непосредственно перед его использованием в вызове функции и хочу свести к минимуму синтаксис для ясности. например:
источник
Из C ++ FAQ Lite :
источник
Одно из мест, где структура была полезна для меня, - это когда у меня есть система, которая получает сообщения фиксированного формата (скажем, последовательный порт) из другой системы. Вы можете преобразовать поток байтов в структуру, которая определяет ваши поля, а затем легко получить доступ к полям.
Очевидно, это то же самое, что вы сделали бы в C, но я обнаружил, что накладные расходы, связанные с декодированием сообщения в класс, обычно не стоят того.
источник
operator >>
класс вместо написанияprocessMessage
функции, которая сделает ваш C ++ более похожим на правильный C ++ и менее похожим на C.__packed__
структуру и иметь реализацию ifdef с поддержкой порядка байтов (вам нужно перевернуть порядок на машине, где порядок байтов противоположен внешнему источнику данных обеспечивает). Это не красиво, но я использовал для упаковки / распаковки регистров для удаленных периферийных устройств на встроенных платформах портативным способом.char
типом, который освобожден от псевдонимов. Тем не менее, есть проблема, хотя и другая: приведениеchar*
к другому типу, если на самом деле не было ни одного объекта последнего типа, уже инициализированного по этому адресу, является UB, поскольку оно нарушает правила жизни. Afaik, даже если тип назначения тривиально конструируем, просто выделение памяти недостаточно для C ++, чтобы формально разрешить обрабатывать эту память как этот тип.Вы можете использовать "struct" в C ++, если вы пишете библиотеку, внутренняя часть которой - C ++, но API может вызываться из кода C или C ++. Вы просто создаете один заголовок, который содержит структуры и глобальные функции API, которые вы открываете как для C, так и для C ++ кода:
Затем вы можете написать функцию bar () в файле C ++, используя код C ++, и сделать его вызываемым из C, и эти два мира смогут обмениваться данными через объявленные структуры. Конечно, при смешивании C и C ++ есть и другие предостережения, но это упрощенный пример.
источник
Как говорят все, единственная реальная разница - доступ по умолчанию. Но я особенно использую struct, когда я не хочу никакой инкапсуляции с простым классом данных, даже если я реализую некоторые вспомогательные методы. Например, когда мне нужно что-то вроде этого:
источник
Чтобы ответить на мой собственный вопрос (бессовестно), как уже упоминалось, привилегии доступа - единственное различие между ними в C ++.
Я склонен использовать структуру только для хранения данных. Я позволю ему получить несколько вспомогательных функций, если это облегчит работу с данными. Однако, как только данные требуют управления потоком (т. Е. Методы получения / установки, которые поддерживают или защищают внутреннее состояние) или начинают получать какие-либо основные функциональные возможности (в основном более объектоподобные), они будут «обновлены» до класса, чтобы лучше передавать намерения.
источник
Структуры ( общем случае POD ) удобны, когда вы предоставляете C-совместимый интерфейс с реализацией C ++, поскольку они переносимы через границы языка и форматы компоновщика.
Если это вас не касается, тогда я полагаю, что использование «struct» вместо «class» является хорошим средством передачи намерений (как сказано выше в @ZeroSignal). Структуры также имеют более предсказуемую семантику копирования, поэтому они полезны для данных, которые вы собираетесь записывать на внешний носитель или передавать по проводам.
Структуры также удобны для различных задач метапрограммирования, таких как шаблоны признаков, которые просто предоставляют набор зависимых типов:
... Но это на самом деле просто использование общедоступного уровня защиты struct по умолчанию ...
источник
Для C ++ между структурами и классами нет большой разницы. Основное функциональное отличие состоит в том, что члены структуры являются открытыми по умолчанию, в то время как они являются закрытыми по умолчанию в классах. В остальном, что касается языка, они эквивалентны.
Тем не менее, я склонен использовать структуры в C ++, как и в C #, подобно тому, что сказал Брайан. Структуры - это простые контейнеры данных, в то время как классы используются для объектов, которые должны воздействовать на данные в дополнение к их удержанию.
источник
Они в значительной степени одно и то же. Благодаря магии C ++, структура может содержать функции, использовать наследование, создаваться с использованием «new» и так далее, как класс
Единственное функциональное отличие состоит в том, что класс начинается с прав частного доступа, а структура начинается с открытого. Это поддерживать обратную совместимость с C.
На практике я всегда использовал структуры как носители данных, а классы - как объекты.
источник
Как уже отмечали другие
Существует четкая рекомендация о том, когда использовать какой из Stroustrup / Sutter:
Тем не менее, имейте в виду, что не стоит отправлять декларацию. как класс (
class X;
) и определить его как struct (struct X { ... }
). Он может работать на некоторых линкерах (например, g ++) и может не работать на других (например, MSVC), так что вы окажетесь в аду разработчиков.источник
class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }
не только компилируется и запускается с MSVC 2017, он даже производит четкое предупреждение, котороеFoo
было объявлено как,struct
но определено какclass
. Но я также хорошо помню, что нашей команде понадобилось полдня, чтобы найти эту глупую ошибку. Я не уверен, какую версию MSVC мы использовали тогда.class
илиstruct
в предварительном объявлении, и эти два свободно взаимозаменяемы в соответствии со стандартом (хотя известно, что VS предупреждает; я всегда предполагал, что это просто для того, чтобы избежать явных ошибок программиста). Здесь что-то не пахнет. Вы уверены, что это не была ошибка нарушения ODR?struct
вперед» на «class
вперед», проблемы исчезли. На сегодняшний день я тоже нахожу это странным. Я был бы рад, если бы вы могли пролить свет на это.Учебный класс.
Члены класса по умолчанию закрыты.
Эквивалентно
Так что если вы попробуете
Мы получим ошибку:
main_one is private
потому что это не доступно. Мы можем решить это, инициализировав его, указав его как общедоступный, т.е.Struct.
Структура - это класс, члены которого по умолчанию являются публичными.
Значит
main_one
частное т.е.Я использую структуры для структур данных, где члены могут принимать любое значение, так проще.
источник
Преимущество по
struct
сравнению с этимclass
заключается в том, что он сохраняет одну строку кода, если придерживается «сначала общедоступных членов, затем частных». В этом свете я нахожу ключевое словоclass
бесполезным.Вот еще одна причина использовать только
struct
и никогдаclass
. В некоторых рекомендациях по стилю кода для C ++ предлагается использовать строчные буквы для макросов функций. Обоснование заключается в том, что при преобразовании макроса во встроенную функцию имя менять не нужно. Тоже самое. У вас есть хорошая структура в стиле C и однажды вы обнаружите, что вам нужно добавить конструктор или какой-нибудь удобный метод. Вы меняете это наclass
? Где угодно?Различение между
struct
s иclass
es - это слишком много хлопот, мешающих делать то, что мы должны делать - программирование. Как и многие из проблем C ++, он возникает из-за сильного желания обратной совместимости.источник
class
? Вы думаете, что класс, определенный с помощьюstruct
ключевого слова, не может иметь функции-члены или конструктор?joe()
должен быть определен сclass
ключевым словом? Каждый класс по крайней мере с 4int
членами должен быть определен сstruct
ключевым словом?struct
агрегатов с методамиclass
». Слишком много хлопот.они одинаковы с разными значениями по умолчанию (частными по умолчанию для
class
и публичными по умолчанию дляstruct
), поэтому теоретически они полностью взаимозаменяемы.поэтому, если я просто хочу упаковать некоторую информацию для перемещения, я использую структуру, даже если я поместил там несколько методов (но не много). Если это в основном непрозрачная вещь, где основное использование будет через методы, а не напрямую членам данных, я использую полный класс.
источник
Структуры по умолчанию имеют открытый доступ, а классы по умолчанию имеют частный доступ.
Лично я использую структуры для объектов передачи данных или как объекты значений. Когда используется как таковой, я объявляю все члены как const, чтобы предотвратить изменение другим кодом.
источник
Оба ,
struct
иclass
один и те же под капотом , хотя с различным по умолчанию как для видимости, поstruct
умолчанию является публичным и поclass
умолчанию является частным. Вы можете изменить одно на другое с соответствующим использованиемprivate
иpublic
. Они оба допускают наследование, методы, конструкторы, деструкторы и все остальные полезности объектно-ориентированного языка.Однако одно огромное различие между ними заключается в том,
struct
что ключевое слово поддерживается в C, аclass
нет. Это означает , что один можно использоватьstruct
в включаемый файл , который может быть#include
в любой C ++ или C до тех пор , какstruct
это обычный стиль Cstruct
и все остальное в инклюднике совместим с C, то есть не C ++ конкретные ключевые слова , такие какprivate
,public
, нет методы, без наследования и т. д. и т. д. и т. п.Стиль AC
struct
может использоваться с другими интерфейсами, которые поддерживают использование стиля Cstruct
для передачи данных назад и вперед по интерфейсу.Стиль AC
struct
- это своего рода шаблон (не шаблон C ++, а шаблон или трафарет), который описывает макет области памяти. На протяжении многих лет интерфейсы пригодными для использования C и C плагинов (здесь смотрит на вас Java и Python и Visual Basic) были созданы некоторые из которых работают в стиле Cstruct
.источник
Технически оба они одинаковы в C ++ - например, структура может иметь перегруженные операторы и т. Д.
Однако :
Я использую структуры, когда я хочу передавать информацию нескольких типов одновременно, я использую классы, когда я имею дело с «функциональным» объектом.
Надеюсь, поможет.
Например, я возвращаю студенту struct здесь методы get ... () - наслаждайтесь.
источник
Я использую,
struct
когда я определяюfunctors
иPOD
. В противном случае я используюclass
.источник
std::binary_function<>
не просто устарел, C ++ 17 даже удаляет его.Я использую структуры, когда мне нужно создать тип POD или функтор.
источник
Все члены класса по умолчанию закрыты, а все члены структуры по умолчанию общедоступны. Класс имеет частные базы по умолчанию, а Struct имеет открытые базы по умолчанию. Struct в случае C не может иметь функции-члены, тогда как в случае C ++ мы можем добавить функции-члены в структуру. Кроме этих различий, я не нахожу в них ничего удивительного.
источник
Я использую struct только тогда, когда мне нужно хранить некоторые данные без каких-либо связанных с ними функций-членов (для работы с данными-членами) и для прямого доступа к переменным данных.
Например: чтение / запись данных из файлов и потоков сокетов и т. Д. Передача аргументов функции в структуре, где аргументов функции слишком много и синтаксис функции выглядит слишком длинным.
Технически между классом и struture нет большой разницы, кроме доступности по умолчанию. Более того, от стиля программирования зависит, как вы его используете.
источник
Я думал, что Structs был задуман как структура данных (например, массив данных с несколькими типами данных), а классы были предназначены для упаковки кода (например, коллекции подпрограмм и функций).
:(
источник
Я никогда не использую "struct" в C ++.
Я не могу представить себе сценарий, в котором вы будете использовать структуру, когда вам нужны частные члены, если вы не пытаетесь вводить в заблуждение.
Кажется, что использование структур - это скорее синтаксическая индикация того, как будут использоваться данные, но я бы предпочел просто создать класс и попытаться сделать это явным в названии класса или в комментариях.
Например
источник
struct
том, что члены класса будут по умолчанию открытыми, не будет уже довольно явным?