2010-05-01 4 views
94

По окончании моего класса C++ мне казалось, что структуры/классы практически идентичны, за исключением нескольких незначительных отличий.C/C++ Struct vs Class

Я никогда не программировал на C раньше; но я знаю, что у него есть структуры. В C можно ли наследовать другие структуры и установить модификатор public/private?

Если вы можете сделать это в обычном C, почему в мире нам нужен C++? Что отличает классы от структуры?

+0

Возможный дубликат http://stackoverflow.com/questions/54585/when-should-you-use-a-class-vs-a-struct-in-c – gonzobrains

+0

Возможный дубликат [Когда вы должны использовать класс vs struct в C++?] (http://stackoverflow.com/questions/54585/when-should-you-use-a-class-vs-a-struct-in-c) – cbuchart

ответ

131

В C++ структуры и классы практически одинаковы; единственная разница заключается в том, что, когда модификаторы доступа (для переменных-членов, методов и базовых классов) в классах по умолчанию являются частными, модификаторы доступа в структурах по умолчанию являются общедоступными.

Однако, в C, структура представляет собой совокупную совокупность (общедоступных) данных и не имеет других классных функций: никаких методов, никакого конструктора, базовых классов и т. Д. Хотя C++ унаследовала ключевое слово , он расширил семантику. (Это, однако, то, почему вещи по умолчанию публичны в structs - структура, написанная как структура C, ведет себя как одна.)

Хотя можно, например, подделать ООП в C —, определяя функции, которые все принимают указатель к структуре как к ее первому параметру, или иногда принудительные структуры с теми же самыми первыми полями, которые должны быть «суб/суперклассами» - это всегда болтовня и на самом деле не является частью языка.

+0

От перспективных .Net ребята OOP определили его [этот путь] (https://msdn.microsoft.com/en-us/library/ms229017 (v = vs.110).aspx) ✓ CONSIDER, определяющий структуру вместо класса, если экземпляры типа являются малыми и обычно недолговечными или обычно внедряются в другие объекты. X AVOID определяет структуру, если тип не имеет всех следующих характеристик: 1. Он логически представляет одно значение, подобное примитивным типам (int, double и т. Д.). 2. У него размер экземпляра не более 16 байт. 3. Это неизменно. – Abhijeet

+2

@Abhijeet Это различие между структурами и классами на C#, но это просто не имеет отношения к C++, а тем более к C. В C# классы и структуры на самом деле разные; не так в C++, и C имеет только структуры без OO. –

6

Это не представляется возможным определить функции-члены или вывести из структур друг с другом в С.

Кроме того, C++ не только C + «выведем структур». Шаблоны, ссылки, пользовательские пространства имен и перегрузка оператора все не существуют в C.

+0

Я знаю, что шаблоны и т. д. не существует в C, но я не знал о «силе» структур в C. Итак, C++ использует только структуры, которые будут «обратно» совместимы с C? – 2010-05-01 14:23:23

+4

Только для обратной совместимости? На практике, вероятно, есть что-то, но различие может быть сигналом намерения: где я использую 'struct', я имею в виду в основном пассивный тип POD thingy. – dmckee

+0

@ dmckee: для чего это стоит, большинство функторов STL (т. Е. 'Std :: less') определяются как структуры, а не классы. –

1

C++ использует структуры в первую очередь для 1) обратной совместимости с C и 2) типов POD. Структуры C не имеют методов, наследования или видимости.

+2

Для чего это стоит, большинство функторов STL (т. Е. 'Std :: less') определяются как структуры, а не классы. –

+2

Обратите внимание, что структуры C++ имеют методы, наследование и видимость. – robertwb

+0

c struct может включать указатель на функцию, но как type (* addr) (params); – Error

12

Другое, что различия в доступе по умолчанию (общедоступные/частные) не отличаются.

Однако некоторые магазины, которые кодируют на C и C++, будут использовать «класс/структура», чтобы указать, что может использоваться в C и C++ (struct) и которые являются только C++ (класс). Другими словами, в этом стиле все структуры должны работать с C и C++. Вот почему, в первую очередь, была разница в прошлом, когда C++ все еще назывался «C с классами».

Обратите внимание, что C-соединения работают с C++, но не наоборот. Например

union WorksWithCppOnly{ 
    WorksWithCppOnly():a(0){} 
    friend class FloatAccessor; 
    int a; 
private: 
    float b; 
}; 

А также

typedef union friend{ 
    int a; 
    float b; 
} class; 

работает только в C

+4

Использование ключевых слов cpp в вашем c-коде, а затем утверждение, что оно не совместимо с cpp, довольно глупо. – Dani

3

еще одно различия в C++, когда вы унаследовать класс от структуры без спецификатора доступа, он становится открытым наследованием, где, как в случае класса это личное наследование.

4

Я собираюсь добавить к существующим ответам, потому что современный C++ теперь вещь и официальный Core Guidelines были созданы, чтобы помочь с такими вопросами, как это.

Вот соответствующий раздел из руководящих принципов:

С.2: Используйте класс, если класс имеет инвариант; используйте конструкцию, если члены данных могут меняться независимо.

Инвариант является логическим условием для членов объекта, которые должен быть установлен конструктором для функций открытого члена. После того, как инвариант установлен (обычно с помощью конструктора), каждая функция-член может быть вызвана для объекта. Инвариант может быть указан неформально (например, в комментарии) или более формально с использованием Expects.

Если все элементы данных могут меняться независимо друг от друга, инвариант невозможен.

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

Enforcement

Ищет структуры со всеми данными частных и классами с государственными членами.

Примеры кода, приведенные:

struct Pair { // the members can vary independently 
    string name; 
    int volume; 
}; 

// but 

class Date { 
public: 
    // validate that {yy, mm, dd} is a valid date and initialize 
    Date(int yy, Month mm, char dd); 
    // ... 
private: 
    int y; 
    Month m; 
    char d; // day 
}; 

Class эс работают хорошо для членов, которые, например, получены друг от друга или взаимосвязаны. Они также могут помочь с проверкой работоспособности при создании экземпляра. Struct s хорошо работает для «мешков данных», где ничего особенного не происходит, но члены логически имеют смысл сгруппировать.

Из этого следует, что существуют class es для поддержки инкапсуляции и других связанных концепций кодирования, которые struct s просто не очень полезны.

+0

Еще одно соображение - переносимость. 'struct' являются наиболее переносимыми. Они могут использоваться C или C++ или назад и вперед. Например, они также могут быть распакованы в Python с использованием модуля 'struct'. Если ваш приоритет проекта совместим с другими языками, интерфейсами или системами, предпочитайте 'struct' over' class'. Для строго программно-внутренних дел предпочитайте «класс». – Dave