C / C ++ Структура проти класу


108

Після закінчення мого класу C ++ мені здалося, що структури / класи практично однакові, за винятком кількох незначних відмінностей.

Я ніколи раніше не програмував на C; але я знаю, що це має структури. Чи можна успадкувати інші структури та встановити модифікатор public / private?

Якщо ви можете це зробити на звичайному C, чому в світі нам потрібен C ++? Що відрізняє класи від структури?

c++  class  struct 

можливо дублікат stackoverflow.com/questions/54585 / ...
gonzobrains

Відповіді:


146

У C ++ структури та класи майже однакові; Єдина відмінність полягає в тому, що де модифікатори доступу (для змінних членів, методів та базових класів) в класах за замовчуванням для приватних, модифікатори доступу в структурах за замовчуванням для загальнодоступних.

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

Хоча можна підробити деякий OOP в C - наприклад, визначити функції, які всі беруть вказівник на структуру як їх перший параметр, або іноді примусові структури з декількома першими тими ж полями, які будуть "під / суперклассами" - це завжди такий собі зафіксований, і насправді це не частина мови.


З перспективного OOP .Net хлопці визначили це таким чином ✓ ВАЖИМО визначити структуру замість класу, якщо екземпляри типу невеликі і зазвичай недовговічні або зазвичай вбудовані в інші об’єкти. X AVOID, що визначає структуру, якщо тип не має всіх наступних характеристик: 1. Логічно представляє єдине значення, подібне до примітивних типів (int, double та ін.). 2. Він має розмір примірника до 16 байт. 3. Це незмінне.
Абхієет

5
@Abhijeet Це різниця між структурами та класами в C #, але це просто не має значення для C ++, а тим більше C. Для C # класи і структури насправді різні; не так у C ++, і C має лише структури без OO.
Antal Spector-Zabusky

не було б краще, щоб у структурі C ++ зберігався той самий семантичний C? і коли вимагається використовувати "структуру в C ++ спосіб" просто використовувати клас? Я ніколи не отримував переваги мати "розширену" структуру на C ++ порівняно з C. Мені подобається, що я все ще використовую структуру, як там, де розроблено в C, інакше використовувати клас, за дозволеним винятком.
Раффаелло

15

Крім того, що різниці в доступі за замовчуванням (публічний / приватний), різниці немає.

Однак деякі магазини, що кодують в C і C ++, будуть використовувати "class / struct", щоб вказати, що можна використовувати в 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;

працює лише в С


9
Використовувати ключові слова cpp у вашому коді c, а потім стверджувати, що це не сумісний cpp, досить нерозумно
Dani

7

Я збираюся додати до існуючих відповідей, тому що сучасний C ++ - це річ, і для створення таких питань, як ці, були створені офіційні Основні рекомендації .

Ось відповідний розділ із посібників:

C.2: використовувати клас, якщо клас має інваріант; використовувати структура, якщо члени даних можуть змінюватись незалежно

Інваріант - це логічна умова для членів об'єкта, яку конструктор повинен встановити, щоб функції публічного члена взяли на себе. Після встановлення інваріанта (як правило, конструктором) для об'єкта може бути викликана кожна функція-член. Інваріант може бути заявлений неофіційно (наприклад, у коментарі) або більше формально, використовуючи очікування.

Якщо всі члени даних можуть змінюватися незалежно один від одного, інваріант не можливий.

Якщо у класу є приватні дані, користувач не може повністю ініціалізувати об'єкт без використання конструктора. Отже, визначник класу надасть конструктор і повинен вказати його значення. Це фактично означає певну потребу визначити інваріант.

Забезпечення виконання

Шукайте структури з усіма приватними даними та класи з громадськими членами.

Наведені приклади коду:

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вони добре працюють для членів, які, наприклад, є похідними один від одного або взаємопов'язаними. Вони також можуть допомогти з перевіркою обґрунтованості при обґрунтуванні. Structs добре працювати над тим, щоб мати "пакети даних", де нічого особливого насправді не відбувається, але члени логічно мають сенс групуватися разом.

З цього має сенс, що classіснують для підтримки інкапсуляції та інших пов'язаних з цим концепцій кодування, для structяких просто не дуже корисно.


Ще одне врахування - портативність. structs - найбільш портативні. Вони можуть використовуватися C або C ++ або назад і назад. structНаприклад, вони також можуть бути розпаковані в Python за допомогою модуля. Якщо ваш проект надає пріоритет сумісності з іншими мовами, інтерфейсами чи системами, віддайте перевагу structнад class. Віддавайте перевагу строго програмно-внутрішнім справам class.
Дейв

6

Неможливо визначити функції члена або отримати структури один від одного в C.

Крім того, C ++ - це не тільки C + "похідні структури". Шаблони, довідники, визначені користувачем простори імен та перевантаження оператора - у C. не існує.


Я знаю, що шаблони тощо не існують в C, але мені не було відомо powerпро структури в C. Отже, тоді C ++ використовує лише структури, щоб бути "назад" сумісними з C?

4
Просто для зворотної сумісності? На практичній основі, мабуть, щось у цьому є, але відмінність може бути сигналом про наміри: де я використовую, structя маю на увазі багато в чому пасивний тип POD.
dmckee --- кошеня колишнього модератора

@dmckee: Для чого це варто, більшість функторів STL (тобто std::less) визначаються як структури, а не класи.
Біллі ONeal

1
C ++ не повністю відповідає сумісному з C. Можна сказати, що ключове слово strukt - це розміщення розробників C. Мені подобається ключове слово Stru для класів, які просто зберігають дані впорядкованому порядку, але самі не надають (багато) логіки.
ypnos

@ypnos: Дивіться мій останній коментар. Єдина відмінність між ними - це те, що члени одного за замовчуванням є загальнодоступними, а інші - приватними.
Біллі ONeal

3

Ще одна відмінність C ++, коли ви успадковуєте клас від struk без будь-якого специфікатора доступу, він стає публічним успадкуванням, де, як і у випадку класу, це приватне успадкування.


1

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


2
Для чого це варто, більшість функторів STL (тобто std::less) визначаються як структури, а не класи.
Біллі ONeal

3
Зауважте, що структури C ++ мають методи, успадкування та видимість.
robertwb

c структура може включати в себе покажчик функції, хоча як тип (* addr) (парами);
Помилка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.