Які відмінності між структурою та класом у C ++?


441

Це питання вже задавались у контексті мережі C # / .

Тепер я хотів би дізнатися про відмінності між структурою та класом в C ++. Будь ласка, обговоріть технічні відмінності, а також причини вибору того чи іншого дизайну ОО.

Почну з очевидної різниці:

  • Якщо ви не вказуєте public:або private:, члени структури за замовчуванням є загальнодоступними; члени класу за замовчуванням приватні.

Я впевнений, що в незрозумілих куточках специфікації C ++ можна знайти інші відмінності.


6
Це посилання добре підсумовує відмінності.
sjsam

1
Чому тоді всі використовують структуру для побудови дерева? Бо здається, що різниця не така вже й велика. До речі, що це відмінний сайт @ sjsam.
JW.ZG

1
Шукаєте різницю між structC і C ++? Дивіться тут .
Марк.2377,

@ JW.ZG Не "всі" люди! Ті, хто робить це, просто віддають перевагу, або не розуміють, що structозначає C ++. ;) Але немає жодної причини, щоб ви не могли використовувати classключове слово натомість.
Гонки легкості на орбіті

Відповіді:


466

Ви забуваєте складну другу різницю між класами та конструкціями.

Вирівнюйте стандарт (§ 11.2.2 в C ++ 98 через C ++ 11):

За відсутності специфікатора доступу для базового класу, публічне передбачається, коли похідний клас оголошується структури, а приватний припускається, коли клас оголошується класом .

І тільки для повноти, більш широко відома різниця між класом і структурою визначена в (11.2):

Член класу , визначений за допомогою ключового слова класу є приватним за замовчуванням. Учасники класу, визначені за допомогою ключових слів структура чи союз , за замовчуванням є загальнодоступними .

Додаткова відмінність: ключове слово classможе використовуватися для оголошення параметрів шаблону, тоді як structключове слово не може бути використане таким чином.


22
Це насправді не є другою відмінністю, це лише те, що питання вказало різницю неповно. Усі суб’єкти за замовчуванням є приватними, коли використовується class, public за замовчуванням з struct, і обидва визначають тип класу.
Бен Войгт

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

104
Власне, справжня хитра різниця між тим structі classполягає в тому, що останній може бути використаний замість typenameанонсування параметра шаблону, тоді як перший не може. :)
sbi

21
@MrUniverse: Це абсолютно неправильно. (Є школа, яка використовує це для конвенції, але це не застосовується синтаксично.)
sbi

3
@sbi «реальна хитра різниця між структурою і класом» - Чарівним, але питанням про різницю між в структури і в класі, а нема про відмінності в якому ключових слова можуть бути використані.
Джим Балтер

161

Цитуючи C ++ FAQ ,

[7.8] Яка різниця між ключовими словами структура та клас?

Учасники та базові класи структури за замовчуванням є загальнодоступними, тоді як у класі вони за замовчуванням приватні. Примітка: ви повинні робити базові класи явно публічними, приватними чи захищеними, а не покладатися на типові параметри.

Структура і клас інакше функціонально еквівалентні.

Гаразд, досить цього писку чистого техно-розмови. Емоційно більшість розробників чітко розрізняють клас та структуру. Структура просто відчуває себе відкритою купою бітів з дуже маленьким способом інкапсуляції чи функціональності. Клас відчуває себе живим і відповідальним членом суспільства з інтелектуальними послугами, сильним бар'єром інкапсуляції та чітко визначеним інтерфейсом. Оскільки це конотація у більшості людей, ви, ймовірно, повинні використовувати ключове слово stru, якщо у вас є клас, який має дуже мало методів і має загальнодоступні дані (такі речі існують у добре розроблених системах!), Але в іншому випадку ви, ймовірно, повинні використовувати клас ключове слово.


123

Варто пам’ятати про походження C ++ та сумісність із C.

C має структури, у нього немає концепції інкапсуляції, тому все є загальнодоступним.

Бути публічним за замовчуванням, як правило, вважається поганою ідеєю при об'єктно-орієнтованому підході, тому при створенні форми C, яка є споконвічною для OOP (ви можете робити ОО в C, але це вам не допоможе), ідея на C ++ (спочатку "C With Classes"), має сенс зробити членів за замовчуванням приватними.

З іншого боку, якби Stroustrup змінив семантику structтак, щоб її учасники за замовчуванням були приватними, це порушило б сумісність (це вже не так часто, як розбігаються стандарти, але всі дійсні програми C були також дійсними програмами C ++, що мало великий вплив на підтримку C ++.

Отже, classбуло введено нове ключове слово, яке точно нагадує структуру, але за замовчуванням приватне.

Якби C ++ прийшов з нуля, не маючи історії, мабуть, він мав би лише одне таке ключове слово. Це також, ймовірно, не зробило б такого впливу.

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


Напевно, також варто відзначити, що, мабуть, простіше, щоб класи та структури працювали однаково під кришкою, ніж їх принципово відрізняти. У ретроспективі може бути якась користь, наприклад, якщо вказати, що все, що оголошується як структура, повинно бути PODS (тобто забороняє структурам мати віртуальних членів, нетривіальних конструкторів за замовчуванням або деструкторів тощо), але таке мені не відомо коли-небудь вимагали будь-який стандарт C ++, ні реалізація.
supercat

1
@supercat той факт, що це мова OO, в якій величезний репертуар програм, написаних мовою, що не є OO, були дійсними програмами, вивів цю концепцію на перший план, і, схоже, вона з’являється більше там, ніж на більш чисто мовах OO (і, звичайно, фактично визначено в стандарті). Історія раннього C ++, безумовно, багато що пояснює про це. "Дизайн та еволюція C ++" Stroustrup - цікаве прочитання.
Джон Ханна

1
Я сприймаю релігійну війну між людьми , які вважають , що все , що не є «OOP-Робочі», мабуть, і ті , хто думає , що ООП слід розглядати як на інструмент, але не на інструмент. С ++, безумовно, охоплює останню філософію, але я насправді мало знаю про мови до цього. Моя власна філософія полягає в тому, що коли хочеться об'єкт, слід використовувати об'єкт, а коли потрібно агрегацію пов'язаних, але незалежних змінних, слід використовувати це. C ++ не робить синтаксичного розрізнення між тими речами, і .NET намагається розмити це розрізнення, але мало що я знаю про D ...
supercat

1
... припускає, що він розпізнає його більше, ніж C ++ або .NET. Агрегації змінних не є саме OOPish, але це не означає, що їх не слід використовувати, коли вони корисні .
supercat

3
Я не погоджуюся з "C має структури, він не має поняття інкапсуляції, тому все є загальнодоступним". Ви можете приховати визначення structвнутрішньої *.c-файли та дозволити іншим підрозділам перекладу використовувати лише це з покажчиком. Отже, у вас є ще сильніша інкапсуляція, оскільки інші підрозділи перекладу навіть не знають, що знаходиться всередині struct.
12431234123412341234123

32

Члени класу за замовчуванням приватні. Учасники структури за замовчуванням є загальнодоступними. Крім того, немає інших відмінностей. Дивіться також це питання .


15
Не тільки члени, але і весь доступ, включаючи спадщину.
Неманья Трифунович

4
Ну, я б сказав, інша різниця - семантика. Бажання багатьох людей змушує їх мислити "структурою даних" як залишком від C.
Кріс Кумлер

3
@KrisKumler: Це не "семантика"; це особисті почуття. Обидва structі classоголошують клас з однаковою семантикою (незважаючи на синтаксичний розбір інтерпретації тіла визначення).
Гонки легкості на орбіті

28

Відповідно до Stroustrup мовою програмування на C ++ :

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

Функціонально немає різниці, окрім публічної / приватної


32
Яка різниця? Будь ласка, поясніть.
crashmstr

10

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

Класи - це різний тип абстрактного типу даних, який намагається забезпечити приховування інформації. Внутрішньо можуть бути різні махінації, методи, тимчасові змінні, змінні стану. тощо, які використовуються для представлення послідовного API будь-якого коду, який бажає використовувати клас.

Фактично, структури - це дані, класи - про код.

Однак вам потрібно зрозуміти, що це просто абстракції. Цілком можливо створити структури, які дуже схожі на класи та класи, схожі на структури. Насправді, найбільш ранні компілятори C ++ були лише попередніми компіляторами, які перекладають код C ++ на C. Таким чином, ці абстракції є користю для логічного мислення, не обов'язково корисністю для самого комп’ютера.

Крім того, що кожен є різним типом абстракції, Класи пропонують рішення головоломки з іменуванням коду С. Оскільки у вас не може бути відкрито більше однієї функції з тим самим іменем, розробники використовували для слідування шаблону _ (). наприклад, mathlibextreme_max (). Групуючи API в класи, подібні функції (тут ми їх називаємо «методами») можна згрупувати разом і захистити від іменування методів в інших класах. Це дозволяє програмісту краще організувати свій код і збільшити повторне використання коду. Теоретично, принаймні.


1
Це найнеочевидніша річ у структурах та класах. "Структури - це дані, класи - про код", можна перефразувати як "структури - це про дані, класи - про дані, безпеку та операції, що виконуються над цими даними"
Арун Аравінд

3
Створити структуру в C ++ неможливо. Створити клас можна лише за допомогою успадкованого structключового слова.
Гонки легкості на орбіті

1
Здається, ця відповідь не стосується C ++. У C ++ structоголошує класи (включаючи public/ private/ protected, успадкування тощо).
мельпомена

Як структури абстрактні? Запис сирих файлів у файл загрожує проблемами навіть на C (звичайні проблеми включають в себе замінник, нестабільність, різний розмір слова тощо). Про що цей SIZEмакрос ви говорите?
Мельпомена

10

1) Учасники класу за замовчуванням приватні, а структури структури за замовчуванням є загальнодоступними.

Наприклад, програма 1 завершує збій, а програма 2 працює чудово.

// Program 1
#include <stdio.h>

class Test {
    int x; // x is private
};
int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
Run on IDE
// Program 2
#include <stdio.h>

struct Test {
    int x; // x is public
};
int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

2) При виведенні структури з класу / структури специфікатор доступу за замовчуванням для базового класу / структури є загальнодоступним. А при виведенні класу специфікатор доступу за замовчуванням приватний.

Наприклад, програма 3 не спрацьовує в компіляції, а програма 4 працює чудово.

// Program 3
#include <stdio.h>

class Base {
public:
    int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base {}

int main()
{
  Derived d;
  d.x = 20; // compiler error becuase inheritance is private
  getchar();
  return 0;
}
Run on IDE
// Program 4
#include <stdio.h>

class Base {
public:
    int x;
};

struct Derived : Base { }; // is equilalent to struct Derived : public Base {}

int main()
{
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}

Я видалив приклади коду 3-7, як згадували експерти
Suraj K Thomas

8

Єдина інша відмінність - це успадкування класів і структур за замовчуванням, яке, як не дивно, є приватним і публічним відповідно.


5
  1. Члени структури за замовчуванням є загальнодоступними, члени класу за замовчуванням приватні.
  2. Спадщина за замовчуванням для структури з іншої структури або класу є загальнодоступною. Спадщина за замовчуванням для класу з іншої структури або класу є приватною.
class A{    
public:    
    int i;      
};

class A2:A{    
};

struct A3:A{    
};


struct abc{    
    int i;
};

struct abc2:abc{    
};

class abc3:abc{
};


int _tmain(int argc, _TCHAR* argv[])
{    
    abc2 objabc;
    objabc.i = 10;

    A3 ob;
    ob.i = 10;

    //A2 obja; //privately inherited
    //obja.i = 10;

    //abc3 obss;
    //obss.i = 10;
}

Це на VS2005.


_tmainне є стандартним C ++.
мельпомена

4

Не в специфікації, ні. Основна відмінність полягає в очікуванні програміста, коли вони читають ваш код через 2 роки. споруди часто вважають ПОД. Структури також використовуються в метапрограмуванні шаблонів, коли ви визначаєте тип для інших цілей, ніж визначення об'єктів.


4

Ще одне, що слід зазначити, якщо ви оновили застарілий додаток, який мав труднощі використовувати класи, ви можете зіткнутися з наступною проблемою:

Старий код має структури, код був очищений і змінився на класи. Потім до нового оновленого класу було додано віртуальну функцію або дві.

Коли віртуальні функції перебувають у класах, то внутрішньо компілятор додасть додатковий покажчик до даних класу, щоб вказати на функції.

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


1
Код, який використовує memfill для очищення структури, ймовірно, має й інші образливі звички. Ідіть обережно.
Девід Торнлі

@DavidThornley: Використання нульового заповнення для стирання або ініціалізації структури даних є стандартним для C. У проекті зі змішаною мовою не можна очікувати, що код у частині С уникне callocна користь new. Все, що можна зробити, - це спробувати переконатися, що будь-які структури, що використовуються частиною C, є насправді PODS.
supercat

4
  1. Член класу, визначений за ключовим словом class, privateза замовчуванням. Учасники класу, визначені за ключовими словами struct(або union), publicза замовчуванням.

  2. За відсутності специфікатора доступу для базового класу, publicпередбачається, коли похідний клас оголошено structі privateпередбачається, коли клас оголошено class.

  3. Ви можете оголосити, enum classале не enum struct.

  4. Можна використовувати, template<class T>але ні template<struct T>.

Зауважимо також, що стандарт C ++ дозволяє переадресовувати тип як a struct, а потім використовувати classпри оголошенні типу і навпаки. Крім того , std::is_class<Y>::valueце trueдля Y бути structі class, але falseдля enum class.


приємна відповідь, хоча я пропускаю явне безпомилкове 0) різниця між structі classв c ++ - це різниця між ключовими словами, а не між типами даних (або якоюсь кращою альтернативою;)
idclev 463035818

@ bivlyknownas_463035818: Але ви не думаєте, що це std::is_class<Y>::valueохоплює?
Вірсавія

Так, я просто подумав, що це може бути більш помітним, тому що це загальне непорозуміння, і колись це перешкоджає решті, це лише наслідки.
idclev 463035818

Не забудьте, ваша відповідь ідеальна, як є, я написав ще одну, не завадить мати ще одного
idclev 463035818

4

Різниця між classі struct- це різниця між ключовими словами, а не між типами даних. Це два

struct foo : foo_base { int x;};
class bar : bar_base { int x; };

обидва визначають тип класу. Різниця ключових слів у цьому контексті полягає в різному доступі за замовчуванням:

  • foo::xє публічним і foo_baseуспадковується публічно
  • bar::xє приватним і bar_baseуспадковується приватно

2

Ось хороше пояснення: http://carcino.gen.nz/tech/cpp/struct_vs_class.php

Отже, ще один раз: у C ++ структура є ідентичною класу, за винятком того, що члени структури мають публічну видимість за замовчуванням, але члени класу мають приватну видимість за замовчуванням.


2

Це просто умовність. Структури можуть бути створені для зберігання простих даних, але пізніше розвиваються час за допомогою додавання функцій-членів та конструкторів. З іншого боку, незвично бачити що-небудь, крім загальнодоступного: доступ до структури.


2

ISO IEC 14882-2003

9 класи

§3

Структура - це клас, визначений класом-ключем struct ; його члени та базові класи (п. 10) за замовчуванням є загальнодоступними (п. 11).


2

Ще одна основна відмінність - це стосується шаблонів. Наскільки я знаю, ви можете використовувати клас, коли визначаєте шаблон, але НЕ структуру.

template<class T> // OK
template<struct T> // ERROR, struct not allowed here

1
Якщо ви мали намір підкреслити, що структури не можна використовувати як узагальнені типи, то ви помиляєтесь. І structце не дозволено лише умовно (краще сказати, що це classключове слово, яке тут використовується в іншому сенсі, див. Для параметрів шаблону 'class' або 'typename' ).
dma_k

Ключове слово там заборонено, але ви можете перейти до класу, який ви визначили, structпросто добре. Просто спробуйте. struct T{}; template <typename T> void foo() {} foo<T>();
Гонки легкості на орбіті

1

В інших відповідях згадуються приватні / публічні за замовчуванням (але зауважте, що структура - це клас, це структура; вони не є двома різними елементами, лише два способи визначення одного і того ж елемента).

Що може бути цікаво відзначити (тим більше, що запитувач, ймовірно, використовує MSVC ++, оскільки він згадує про "некерований" C ++), це те, що Visual C ++ скаржиться за певних обставин, якщо клас оголошується з, classа потім визначається з struct(або, можливо, навпаки ), хоча стандарт говорить, що це абсолютно законно.


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

1
  • . У класах всі члени за замовчуванням є приватними, але в структурі члени за замовчуванням є загальнодоступними.

    1. Не існує терміна, як конструктор і деструктор для структур, але компілятор класів створює за замовчуванням, якщо ви не надаєте.

    2. Розмір порожньої структури дорівнює 0 байтів, оскільки розмір порожнього класу дорівнює 1 байту Тип доступу за замовчуванням за структурою є загальнодоступним. Для групування даних зазвичай слід використовувати структуру.

    Тип доступу за замовчуванням для класу - приватний, а режим спадкування за замовчуванням - приватний. Клас повинен використовуватися для групування даних і методів, які працюють на цих даних.

    Коротше кажучи, умовою є використання структури, коли метою є групування даних, і використання класів, коли нам потрібна абстракція даних і, можливо, успадкування.

    У C ++ структури та класи передаються за значенням, якщо явно не посилаються на них. В інших мовах класи та структури можуть мати різну семантику - тобто. об'єкти (екземпляри класів) можуть передаватися посиланням, а структури можуть передаватися за значенням. Примітка. У цьому питанні є коментарі. Дивіться сторінку обговорення, щоб додати до розмови.


3
"2. Sizeof порожня структура дорівнює 0 байтів, оскільки клас Sizeof порожній - 1 байт". Помилковий. Я щойно тестував g++. Ви можете думати про оптимізацію порожньої бази, але це стосується і обох.
cdunn2001

1
Неправда. У C ++ розмір порожньої структури дорівнює 1. У C порожня структура заборонена. GCC дозволяє пусті структури в C як розширення компілятора, і така структура має розмір 0.
Йохан Råde,

Ця відповідь неправильна. На додаток до розміру, конструкція / деструктор також є неточними: конструкції можуть мати конструктори та деструктори просто чудово. Фактично structстворює повноцінні класи в C ++.
Мельпомена

1

Хоча маються на увазі інші відповіді, це прямо не зазначено - що структури сумісні з C, залежно від використання; заняття немає.

Це означає, що якщо ви пишете заголовок, який ви хочете бути сумісним з C, то у вас немає іншого варіанту, крім struktur (який у світі C не може мати функцій; але може мати покажчики функцій).


-1

Ви можете розглянути це як рекомендації щодо того, як рухатись до структури або класу, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

√ ВАЖИМО визначити структуру замість класу, якщо екземпляри типу невеликі і зазвичай недовговічні або вбудовані в інші об'єкти.

X AVOID, що визначає структуру, якщо тип не має всіх наступних характеристик:

Він логічно представляє єдине значення, схоже на примітивні типи (int, double та ін.).

Він має розмір примірника до 16 байт.

Це незмінне.

Боксувати не доведеться часто.


Йдеться про .NET / C #, а не C ++.
Мельпомена

-2

Клас має значення лише в контексті інженерії програмного забезпечення. У контексті структур даних та алгоритмів, клас і структура не так вже й відрізняються. Немає жодного правила, обмеженого посиланням на члена класу.

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

Якщо ви прочитаєте деякі принципи інженерії програмного забезпечення, то виявите, що більшість стандартів неможливо запровадити легко без класу. наприклад: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

BTW: Коли структура виділяє хруст пам'яті і включає декілька змінних, змінні типу значень вказують на те, що значення вбудовані в структуру, де розподілено. На відміну від цього, значення змінної типу посилання є зовнішніми та посиланнями вказівником, який також вбудований у структуру розподіленої структури.


Здається, ця відповідь не стосується C ++. В C ++ structоголошує класи (включаючи контроль дозволів, успадкування тощо).
Мельпомена

-3

Різниця між ключовими словами stru і class у C ++ полягає в тому, що коли немає конкретного специфікатора для конкретного складеного типу даних, то за замовчуванням структура або об'єднання - це загальнодоступні ключові слова, які просто враховують приховування даних, але клас - це приватне ключове слово, яке враховує приховування програми коди або дані. Завжди деякі програмісти використовують stru для даних та класу заради коду. Для отримання додаткової інформації зверніться до інших джерел.


ОП вже згадувало, що structчлени за замовчуванням є загальнодоступними, а прийнята відповідь з 2009 року згадує спадщину. Навіщо писати ще одну відповідь, яка не додає нової інформації через 4 роки?
мельпомена

-3

З усіх цих факторів можна зробити висновок, що концепт Клас дуже підходить для представлення реальних об'єктів світу, а не "Структури". Велике тому, що поняття OOP, що використовуються в класі, є дуже практичними для пояснення сценаріїв реального світу, тому їх легше об'єднати з реальністю. Наприклад, успадкування за замовчуванням є загальнодоступним для структур, але якщо ми застосовуємо це правило для реального світу, це смішно. Але в класі спадкування за замовчуванням є приватним, що більш реалістично.

У будь-якому разі, що мені потрібно обґрунтувати, це Клас - це набагато ширше, застосовне до реального світу поняття, тоді як Структура - це примітивна концепція з поганою внутрішньою організацією (навіть якщо структура дотримується концепцій ООП, вони мають слабке значення)


1
Як приватне успадкування "реалістичніше"? Більшість мов програмування навіть не мають поняття приватного успадкування.
Мельпомена

-3

Основна відмінність ключового слова структури та класу в oops полягає в тому, що в структурі немає жодного публічного та приватного декларації учасника. Функція члена та члена не може бути визначена як публічна, приватна, а також захищена.


Здається, ця відповідь не стосується C ++. У C ++ structоголошує класи (включаючи public/ private/ protected, успадкування тощо).
мельпомена

-3

** ОНОВЛЕННЯ: ** Будь ласка, проігноруйте цю відповідь. Я не вважав можливістю того, що для struct значення було неініціалізоване, але просто сталося 0. Немає різниці в ініціалізації між struct і class.


Я бачу ще один різний між структурами та класами, що стосується ініціалізації за замовчуванням.

struct Foo {
    int a;
};

class Bar {
    int a;
};

class Tester {
    Foo m_Foo = Foo();
    Bar m_Bar = Bar();

public:
    Tester() {}
};

int main() {
    auto myTester = Tester();
}

Запустіть цей код і вивчіть мій тестер. Ви побачите, що для m_Foo структура, m_Foo.a ініціалізована до 0, але для m_Bar клас m_Bar.a неініціалізований. Так що, схоже, є різниця в тому, що конструктор за замовчуванням робить для struct vs. class. Я бачу це з Visual Studio.


1
Як ви визначили, що m_Foo.aбуло ініціалізовано? Що робити, якщо це було неініціалізоване і щойно сталося 0?
мельпомена

Ух, я не став. Моє ліжко. Це не різниця між структурою та класом. Характеристики ініціалізації однакові.
Ерік Хілл

-4

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

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

Але це залежить від програміста, яким чином він / вона вважає підходящим ... на мою думку, я віддаю перевагу класу щоразу тільки тому, що він підтримує OOP, і саме тому він реалізується майже на всіх мовах і є чудовою особливістю програмування всіх часів; - )

І так, найбільш незабутня різниця, яку я забув згадати, полягає в тому, що клас підтримує приховування даних, а також підтримує операції, які виконуються на вбудованих типах даних, в той час як struct doesnt!


1
У C ++ structможуть бути функції учасників
chtz

@chtz Спасибі ... я дізнався про цю функцію саме зараз ... дякую .. я просто початківець не такий досвідчений, як ви, так що в майбутньому також потрібні поради у хлопців :-)
Юг Равал

і насправді функція члена повинна бути призначена в її більш широкому значенні. structможе мати конструктори, функції членів та дистрибутор (можливо, віртуальний, можливо приватний, захищений або загальнодоступний). Вони можуть успадковуватись і передаватися у спадок. так що насправді ... все, що може мати клас. типовим умовою є оголосити за допомогою структури те, що ви б оголосили як структура в C, і як клас, якщо ми оголосимо приватну і захищену змінну, віртуальні функції, ctor і dtor тощо. Але це лише умова, не виконана мовою
Джан Паоло

-5

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


4
Це не правда. Не існує різниці між класом, визначеним structключовим словом, і класом, визначеним із classключовим словом у цьому відношенні.
ymett

коли я використовую структуру з конструктором, я отримую кращу швидкість, ніж клас з конструктором.
Алі

@Ali Ні, ти цього не робиш.
Гонки легкості по орбіті

-5

Класи - це еталонні типи, а структури - типи значень.
Коли я кажу, що Класи - це еталонні типи,
вони в основному містять адресу змінних екземплярів.

Наприклад:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

В основному методі
я можу створити екземпляр цього класу, використовуючи новий оператор, який виділяє пам'ять для цього класу
і зберігає базовий адресу цього типу в змінну типу MyClass (_myClassObject2).

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

У вищезгаданій програмі MyClass _myClassObject2 = _myClassObject1; інструкція вказує, що обидві змінні типу MyClass

  1. myClassObject1
  2. myClassObject2

і вказуватиме на те саме місце пам'яті.
В основному він призначає те саме місце пам'яті в іншій змінній того ж типу.

Тож якщо будь-які зміни, які ми вносимо в будь-який з об'єктів типу MyClass, матимуть вплив на інший,
оскільки обидва вказують на одне місце пам’яті.

"_myClassObject1.DataMember = 10;" у цьому рядку обидва учасники даних об’єкта будуть містити значення 10.
"_myClassObject2.DataMember = 20;" у цьому рядку обидва учасника даних об’єкта містять значення 20.
Зрештою, ми отримуємо доступ до членів даних об’єкта за допомогою покажчиків.

На відміну від класів, структури є ціннісними типами. Наприклад:

Structure MyStructure
{
    Public Int DataMember;  //By default, accessibility of Structure data 
                            //members will be private. So I am making it as 
                            //Public which can be accessed out side of the structure.
}

Static Public void Main (string[] arg)
{
    MyStructure _myStructObject1 = new MyStructure();
    _myStructObject1.DataMember = 10;

    MyStructure _myStructObject2 = _myStructObject1;
    _myStructObject2.DataMember = 20;
}

У вищезгаданій програмі
інстанціювання об'єкта типу MyStructure за допомогою нового оператора та
збереження адреси у змінній _myStructObject типу MyStructure та
присвоєння значенню 10 члену структури структури за допомогою "_myStructObject1.DataMember = 10".

У наступному рядку
я декларую іншу змінну _myStructObject2 типу MyStructure і призначаю їй _myStructObject1.
Тут компілятор .NET C # створює ще одну копію об’єкта _myStructureObject1 і
призначає це місце пам'яті в змінну MyStructure _myStructObject2.

Отже будь-яка зміна, яку ми вносимо до _myStructObject1, ніколи не матиме впливу на іншу змінну _myStructObject2 типу MyStructrue.
Ось чому ми говоримо, що Структури - цінні типи.

Отже, безпосередній клас Base для класу - Object, а безпосередній клас Base для Structure - це ValueType, який успадковується від Object.
Класи підтримуватимуть наслідування, тоді як структури не будуть.

Як ми це говоримо?
І в чому причина цього?
Відповідь - Заняття.

Він може бути абстрактним, запечатаним, статичним та частковим і не може бути приватним, захищеним та захищеним внутрішнім.


4
Я думаю, що це намагається відповісти на питання для c #? Питання стосується c ++, і це робить цю відповідь неточною, правда?
smw

@smw абсолютно, він написав свій зразок коду в C #, і я прийшов сюди, щоб перевірити, чи не було різниці в переході параметрів між C ++ structі class. Ніхто тут не згадував про це, ані всю мережу. Тому я не думаю, що це стосується і C ++.
Джон

Це навіть не дійсний код C # - усі ключові слова неправильні. "Громадський", "Статичний", "Int" та "Клас" не повинні використовуватися з великої літери, і він повинен бути "struct", а не "Structure". Опис здебільшого точний для C # (хоча структури все ще можуть успадковувати інтерфейси, тільки не інші структури), але не відповідає на питання, оскільки мова йшла про C ++ ...
Darrel Hoffman

2
Ця відповідь є повною нісенітницею. Для його прикладів коду використовується дивна суміш Visual Basic та C #, а ціле "Класи - це типові типи, а структури - це типи значень" ... річ стосується лише .NET (тобто C #), а не C ++. Ти в неправильній кімнаті, чувак. Це де ви належите: stackoverflow.com/questions/13049
TheFlash

Але ця відповідь вказує, що те ж саме справедливо і для C (++), що структури використовуються як типи значень. int a = 3; int b = a;та подібніMyStruct a=MyStruct("data"); MyStruct b = a;
luckydonald

-8

Існує 3 основні відмінності між структурою та класом

1St- пам'ять зарезервована для структури в пам'яті стека (що знаходиться поруч з мовою програмування), будь то для класу в пам'яті стека зарезервовано тільки для відтворення, а фактична пам'ять зарезервована в купі пам'яті.

2Nd - Структура за замовчуванням трактується як загальнодоступна, чи клас трактується як приватний.

3Rd - не може повторно використовувати код у структурі, але в класі ми можемо повторно використовувати той самий код у багатьох випадках, який називається спадковістю


2
С ++ структури підтримують успадкування та абстрактні методи. Структура та клас розподіляються однаково. Розміщення класу на купі, навіть якщо вони не створені інстанцією з "новим", не має сенсу для вбудованих систем.
JCMS

2
№1 також неправильно. Стек використовується, коли ви декларуєте щось такого типу як локальну змінну, а купа використовується при використанні оператора "new".
Score_Under
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.