Jakie są różnice między strukturą a klasą w C ++?


441

To pytanie zostało już zadane w kontekście C # / .Net .

Teraz chciałbym poznać różnice między strukturą a klasą w C ++. Omów różnice techniczne, a także powody wyboru jednego lub drugiego projektu OO.

Zacznę od oczywistej różnicy:

  • Jeśli nie określisz public: lub private:, członkowie struktury są domyślnie publiczni; członkowie klasy są domyślnie prywatni.

Jestem pewien, że istnieją inne różnice w niejasnych rogach specyfikacji C ++.


6
Ten link dobrze podsumowuje różnice.
sjsam,

1
Dlaczego więc wszyscy używają struct do budowy drzewa? Ponieważ wydaje się, że różnica nie jest aż tak duża. BTW, To świetna strona internetowa. @ Sjsam
JW.ZG

1
Szukasz różnicy między structC i C ++? Zobacz tutaj .
Marc.2377,

@ JW.ZG Nie wszyscy tak robią! Ci, którzy to robią, po prostu wolą lub nie zdają sobie sprawy, co structoznacza C ++. ;) Ale nie ma powodu, dla którego nie można użyć tego classsłowa kluczowego.
Wyścigi lekkości na orbicie

Odpowiedzi:


466

Zapominasz trudną drugą różnicę między klasami a strukturami.

Cytuj standard (§ 11.2.2 w C ++ 98 do C ++ 11):

W przypadku braku dostępu-specyfikacją dla klasy podstawowej, publicznego zakłada gdy klasa pochodna jest zadeklarowany struct i prywatnego zakłada, gdy klasa jest zadeklarowana klasę .

I dla samej kompletności, bardziej znana różnica między klasą a strukturą jest zdefiniowana w (11.2):

Członek klasy zdefiniowanej ze słowem kluczowym klasyprywatne domyślnie. Członkowie klasy zdefiniowanej za pomocą słów kluczowych struct lub union są domyślnie publiczni .

Dodatkowa różnica: słowa kluczowego classmożna użyć do zadeklarowania parametrów szablonu, a structsłowa kluczowego nie można użyć w ten sposób.


22
To nie jest tak naprawdę druga różnica, tylko to, że pytanie podało różnicę niecałkowicie. Wszystkie podobiekty są domyślnie prywatne podczas korzystania z class, public z structi oba określają typ klasy.
Ben Voigt,

10
Myślę, że przegapiłeś sedno, Ben. To dziedzictwo jest publiczne dla struktur i prywatne dla klas. To bardzo ważne rozróżnienie i całkowicie niezwiązane z faktycznym dostępem członków. Na przykład język mógł bardzo dobrze zdefiniować go w inny sposób, np. Oba są domyślnie dziedziczone publicznie, a Ty miałbyś bardzo różne implikacje.
Assaf Lavie,

104
W rzeczywistości prawdziwa trudna różnica pomiędzy structi classpolega na tym, że ten ostatni może być użyty zamiast typenamedeklarować parametr szablonu, podczas gdy ten pierwszy nie. :)
sbi

21
@MrUniverse: To jest całkowicie błędne. (Jest szkoła, która wykorzystuje to do konwencji, ale nie jest ona wymuszona składniowo.)
sbi

3
@sbi „prawdziwa różnica między skomplikowane struktury i klasy” - ładny, ale pytanie jest o różnicę między pomocą struktury oraz w klasie, a nie o różnice w którym mogą być stosowane słowa kluczowe.
Jim Balter

161

Cytując C ++ FAQ ,

[7.8] Jaka jest różnica między słowami kluczowymi struct a klasą?

Członkowie i podstawowe klasy struktury są domyślnie publiczne, podczas gdy w klasie domyślnie są prywatne. Uwaga: powinieneś jawnie uczynić swoje klasy podstawowe publicznymi, prywatnymi lub chronionymi, zamiast polegać na ustawieniach domyślnych.

Struktura i klasa są poza tym funkcjonalnie równoważne.

OK, dość tej piszczącej czystej techno. Emocjonalnie większość programistów dokonuje wyraźnego rozróżnienia między klasą a strukturą. Struktura po prostu wydaje się być otwartą stertą bitów z bardzo małą ilością możliwości enkapsulacji lub funkcjonalności. Klasa czuje się jak żywy i odpowiedzialny członek społeczeństwa z inteligentnymi usługami, silną barierą hermetyzacji i dobrze zdefiniowanym interfejsem. Ponieważ taka konotacja ma już większość ludzi, prawdopodobnie powinieneś użyć słowa kluczowego struct, jeśli masz klasę, która ma bardzo mało metod i dane publiczne (takie rzeczy istnieją w dobrze zaprojektowanych systemach!), Ale w przeciwnym razie prawdopodobnie powinieneś użyć tej klasy słowo kluczowe.


123

Warto pamiętać o pochodzeniu C ++ i zgodności z C.

C ma struktury, nie ma pojęcia enkapsulacji, więc wszystko jest publiczne.

Bycie publicznym domyślnie jest ogólnie uważane za zły pomysł, gdy przyjmuje się podejście zorientowane obiektowo, więc tworząc formę C, która natywnie sprzyja OOP (możesz robić OO w C, ale to ci nie pomoże), co było pomysł w C ++ (pierwotnie „C z klasami”), domyślnie sensowne jest ustawienie członków jako prywatnych.

Z drugiej strony, gdyby Stroustrup zmienił semantykę struct tak, aby jego członkowie byli domyślnie prywatni, to zepsułby kompatybilność (nie jest już tak często prawdą, jak rozbieżne standardy, ale wszystkie prawidłowe programy C były również poprawnymi programami C ++, co miało duży wpływ na zapewnienie C ++ przyczółka).

classWprowadzono więc nowe słowo kluczowe, które jest dokładnie takie jak struct, ale domyślnie jest prywatne.

Gdyby C ++ powstał od zera, bez historii, prawdopodobnie miałby tylko jedno takie słowo kluczowe. Prawdopodobnie nie wywarłoby to również takiego wpływu.

Ogólnie rzecz biorąc, ludzie będą mieli tendencję do korzystania z struct, gdy robią coś takiego, jak struktury są używane w C; członkowie publiczni, brak konstruktora (o ile nie jest on w związku, można mieć konstruktory w strukturach, tak jak w przypadku klas, ale ludzie raczej tego nie robią), brak metod wirtualnych itp. Ponieważ języki są w równym stopniu komunikowane z ludzie czytający kod instruujący maszyny (w przeciwnym razie trzymalibyśmy się kodami asemblera i surowymi maszynami wirtualnymi), warto trzymać się tego.


Prawdopodobnie warto również zauważyć, że prawdopodobnie łatwiej było mieć takie same klasy i struktury działające pod maską, niż mieć je zasadniczo różne. Z perspektywy czasu może być pewna korzyść polegająca np. Na sprecyzowaniu, że wszystko zadeklarowane jako struktura musi być PODS (tj. Zabrania strukturom posiadania wirtualnych elementów, nietrywialnych domyślnych konstruktorów lub destruktorów itp.), Ale coś takiego nie jest, według mojej wiedzy, były kiedykolwiek wymagane przez jakikolwiek standard C ++ ani implementację.
supercat

1
@supercat fakt, że był to język OO, w którym szeroki repertuar programów napisanych w języku innym niż OO był prawidłowy, wysunął tę koncepcję na pierwszy plan i wydaje się, że pojawia się on częściej niż w językach czysto OO (i oczywiście jest faktycznie zdefiniowany w standardzie). Historia wczesnego C ++ zdecydowanie o tym wiele wyjaśnia. Interesująca lektura autorstwa The Stroustrup „The Design and Evolution of C ++”.
Jon Hanna,

1
Widzę wojnę religijną między ludźmi, którzy czują, że wszystko, co nie jest „oop-owski”, powinno być, a ci, którzy uważają, że OOP powinny być uważane za pomocą narzędzia, ale nie na narzędzia. C ++ z pewnością zdaje się przyjmować tę drugą filozofię, ale tak naprawdę niewiele wiem o językach przed nią. Moja własna filozofia jest taka, że ​​jeśli ktoś chce obiektu, powinien go użyć, a gdy chce się agregacji powiązanych, ale niezależnych zmiennych, powinien tego użyć. C ++ nie dokonuje żadnego syntaktycznego rozróżnienia między tego rodzaju rzeczami, a .NET próbuje zatrzeć to rozróżnienie, ale mało wiem o D ...
supercat

1
... sugeruje, że rozpoznaje go bardziej niż C ++ lub .NET. Agregacje zmiennych nie są dokładnie OOPish, ale to nie znaczy, że nie powinny być stosowane, gdy są przydatne .
supercat

3
Nie zgadzam się z „C ma struktury, nie ma pojęcia enkapsulacji, więc wszystko jest publiczne.”, Możesz ukryć definicję structpliku *.c-File i pozwolić innym jednostkom tłumaczeniowym używać go tylko ze wskaźnikiem. Masz więc jeszcze silniejszą enkapsulację, ponieważ inne jednostki tłumaczeniowe nawet nie wiedzą, co jest w środku struct.
12431234123412341234123

32

Członkowie klasy są domyślnie prywatni. Członkowie Struct są domyślnie publiczni. Poza tym nie ma innych różnic. Zobacz także to pytanie .


15
Nie tylko członkowie, ale cały dostęp, w tym dziedziczenie.
Nemanja Trifunovic

4
Powiedziałbym, że inną różnicą jest semantyka. Struktura dla wielu ludzi sprawia, że ​​myślą „strukturę danych” jako pozostałość po C.
Kris Kumler,

3
@KrisKumler: To nie są „semantyki”; są to osobiste uczucia. Zarówno structi classzadeklarować klasę z identycznych semantyki (mimo wszystko parse mądry interpretacji ciała Definition).
Lekkość ściga się na orbicie

28

Według Stroustrup w języku programowania C ++ :

Wybór stylu zależy od okoliczności i smaku. Zwykle wolę używać structdla klas, które mają wszystkie dane publiczne. Myślę o takich klasach jako „niezupełnie odpowiednich typach, tylko strukturach danych”.

Funkcjonalnie nie ma żadnej różnicy poza publiczną / prywatną


32
Co za różnica? Proszę wytłumacz.
crashmstr

10

STRUCT jest rodzajem abstrakcyjnego typu danych, który dzieli dany fragment pamięci zgodnie ze specyfikacją struktury. Struktury są szczególnie przydatne w serializacji / deserializacji pliku, ponieważ struktura może być często zapisywana w pliku dosłownie. (tj. Uzyskaj wskaźnik do struktury, użyj makra SIZE, aby obliczyć liczbę bajtów do skopiowania, a następnie przenieś dane do lub z struktury).

Klasy to inny typ abstrakcyjnych typów danych, które próbują zapewnić ukrywanie informacji. Wewnętrznie może istnieć wiele machinacji, metod, zmiennych temp, zmiennych stanu. itp., które wszystkie służą do prezentacji spójnego API dla każdego kodu, który chce użyć klasy.

W efekcie struktury dotyczą danych, klasy dotyczą kodu.

Musisz jednak zrozumieć, że są to jedynie abstrakcje. Zupełnie możliwe jest tworzenie struktur, które wyglądają bardzo podobnie do klas i klas, które wyglądają bardzo podobnie do struktur. W rzeczywistości najwcześniejsze kompilatory C ++ były jedynie prekompilatorami, które tłumaczą kod C ++ na C. Dlatego te abstrakcje są zaletą logicznego myślenia, niekoniecznie atutem dla samego komputera.

Oprócz tego, że każdy z nich jest innym rodzajem abstrakcji, Klasy zapewniają rozwiązania zagadki nazewnictwa kodu C. Ponieważ nie można udostępnić więcej niż jednej funkcji o tej samej nazwie, programiści stosowali wzorzec _ (). np. mathlibextreme_max (). Grupując interfejsy API w klasy, podobne funkcje (tutaj nazywamy je „metodami”) można grupować razem i chronić przed nazywaniem metod w innych klasach. Pozwala to programiście lepiej zorganizować swój kod i zwiększyć jego ponowne użycie. Przynajmniej w teorii.


1
Jest to najbardziej nieoczywista rzecz w strukturach i klasach. „Struktury dotyczą danych, klasy dotyczą kodu” można przeformułować, ponieważ „struktury dotyczą danych, klasy dotyczą danych, bezpieczeństwa i operacji wykonywanych na tych danych”
Arun Aravind

3
Nie można utworzyć struktury w C ++. Możliwe jest utworzenie klasy tylko przy użyciu odziedziczonego structsłowa kluczowego.
Wyścigi lekkości na orbicie

1
Ta odpowiedź nie dotyczy C ++. W C ++ structdeklaruje klasy (w tym public/ private/ protected, dziedziczenie itp.).
melpomene

W jaki sposób struktury są abstrakcyjne? Pisanie surowych struktur do pliku jest obarczone problemami nawet w C (typowe problemy to dopełnianie, endianness, inny rozmiar słowa itp.). O czym jest to SIZEmakro, o którym mówisz?
melpomene

10

1) Członkowie klasy są domyślnie prywatni, a członkowie struct są domyślnie publiczni.

Na przykład program 1 nie działa podczas kompilacji, a program 2 działa dobrze.

// 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) Podczas uzyskiwania struktury z klasy / struktury domyślny specyfikator dostępu dla klasy podstawowej / struktury jest publiczny. Podczas wyprowadzania klasy domyślny specyfikator dostępu jest prywatny.

Na przykład program 3 nie działa podczas kompilacji, a program 4 działa dobrze.

// 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;
}

Usunąłem przykłady kodu 3-7, o których wspominali eksperci
Suraj K Thomas

8

Jedyną inną różnicą jest domyślne dziedziczenie klas i struktur, które, co nie jest zaskoczeniem, odpowiednio prywatne i publiczne.


5
  1. Członkowie struktury są domyślnie publiczni, członkowie klasy są domyślnie prywatni.
  2. Domyślne dziedziczenie struktury z innej struktury lub klasy jest publiczne. Domyślne dziedziczenie dla klasy z innej struktury lub klasy jest prywatne.
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;
}

To jest na VS2005.


_tmainnie jest standardowym C ++.
melpomene

4

Nie w specyfikacji, nie. Główną różnicą są oczekiwania programistów, gdy czytają Twój kod za 2 lata. struktury często są uważane za POD. Struktury są również używane w metaprogramowaniu szablonów, gdy definiujesz typ do celów innych niż definiowanie obiektów.


4

Należy zauważyć jeszcze jedną rzecz: jeśli zaktualizujesz starszą aplikację, która miała struktury do korzystania z klas, możesz napotkać następujący problem:

Stary kod ma struktury, kod został wyczyszczony i zmieniono je na klasy. Następnie do nowej zaktualizowanej klasy dodano funkcję wirtualną lub dwie.

Gdy funkcje wirtualne są w klasach, wówczas kompilator wewnętrznie doda dodatkowy wskaźnik do danych klasy, aby wskazać funkcje.

Jak to zepsuje stary kod, jeśli w starym kodzie gdzieś struktura została wyczyszczona za pomocą memfill, aby wyczyścić wszystko na zerach, to również zniszczy dodatkowe dane wskaźnika.


1
Kod, który używa memfill do czyszczenia struktury, prawdopodobnie ma inne obraźliwe nawyki. Idź ostrożnie.
David Thornley,

@DavidThornley: Użycie zerowego wypełnienia do usunięcia lub zainicjowania struktury danych jest standardem w C. W projekcie w języku mieszanym nie można oczekiwać, że kod w części C zostanie pominięty callocna korzyść new. Wszystko, co można zrobić, to upewnić się, że wszelkie struktury używane przez część C kodu są w rzeczywistości PODS.
supercat

4
  1. Członkowie klasy zdefiniowanej za pomocą słowa kluczowego classprivatedomyślnie. Członkowie klasy zdefiniowanej za pomocą słów kluczowych struct(lub union) są publicdomyślnie.

  2. W przypadku braku specyfikatora dostępu dla klasy bazowej publicprzyjmuje się, gdy klasa pochodna jest zadeklarowana, structi privateprzyjmuje się, gdy klasa jest zadeklarowana class.

  3. Możesz zadeklarować, enum classale nie enum struct.

  4. Możesz użyć, template<class T>ale nie możesz template<struct T>.

Zauważ też, że standard C ++ pozwala na zadeklarowanie typu jako „a” struct, a następnie użycie go classprzy deklarowaniu typu i odwrotnie. Ponadto, std::is_class<Y>::valuejest truedla Y bycia structi class, ale jest falseza enum class.


miła odpowiedź, chociaż brakuje mi wyraźny niewątpliwy 0) różnica między structa classw C ++ jest różnica między słowami kluczowymi, a nie między typami danych (lub lepsza alternatywa;)
idclev 463035818

@ previouslyknownas_463035818: Ale nie sądzisz, że to std::is_class<Y>::valueobejmuje?
Batszeba

tak, po prostu pomyślałem, że może to być bardziej widoczne, ponieważ jest to powszechne nieporozumienie, a kiedy to zejdzie z drogi, reszta to tylko następstwa.
idclev 463035818,

Nieważne, twoja odpowiedź jest idealna, tak jak jest, napisałem inną, nie zaszkodzi mieć jeszcze jedną
idclev 463035818,

4

Różnica między classi structjest różnicą między słowami kluczowymi, a nie między typami danych. Te dwa

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

oba określają typ klasy. Różnicą słów kluczowych w tym kontekście jest inny domyślny dostęp:

  • foo::xjest publiczny i foo_basejest dziedziczony publicznie
  • bar::xjest prywatny i bar_basejest dziedziczony prywatnie


2

To tylko konwencja. Struktury mogą być tworzone do przechowywania prostych danych, ale później ewoluują czas dzięki dodaniu funkcji składowych i konstruktorów. Z drugiej strony niezwykłe jest, aby zobaczyć coś innego niż publiczny: dostęp w strukturze.


2

ISO IEC 14882-2003

9 klas

§3

Struktura to klasa zdefiniowana za pomocą klucza klasy struct ; jego członkowie i klasy podstawowe (klauzula 10) są domyślnie publiczne (klauzula 11).


2

Inna główna różnica dotyczy szablonów. O ile mi wiadomo, możesz użyć klasy podczas definiowania szablonu, ale NIE struktury.

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

1
Jeśli chciałeś podkreślić, że struktur nie można używać jako typów uogólnionych, to jesteś w błędzie. I structnie jest tam dozwolone tylko na podstawie konwencji (lepiej powiedz, że to classsłowo kluczowe jest używane tutaj w innym znaczeniu, zobacz Używanie „class” lub „typename” dla parametrów szablonu ).
dma_k,

Słowo kluczowe jest tam niedozwolone, ale możesz przejść do klasy, którą zdefiniowałeś struct. Po prostu spróbuj. struct T{}; template <typename T> void foo() {} foo<T>();
Wyścigi lekkości na orbicie

1

Inne odpowiedzi wspominały o domyślnych ustawieniach prywatnych / publicznych (ale zauważ, że struct to klasa jest strukturą; nie są to dwa różne elementy, tylko dwa sposoby definiowania tego samego elementu).

Warto zwrócić uwagę (zwłaszcza, że ​​pytający prawdopodobnie używa MSVC ++, ponieważ wspomina o „niezarządzanym” C ++), że Visual C ++ narzeka w pewnych okolicznościach, jeśli klasa jest zadeklarowana za pomocą, classa następnie zdefiniowana za pomocą struct(lub ewentualnie na odwrót ), chociaż standard mówi, że jest to całkowicie legalne.


Wiem, że jest to bardzo późny komentarz, ale pamiętaj, że wspomniane ostrzeżenie nie jest bez znaczenia, ponieważ Windows ABI zmienia struktury i klasy inaczej i dlatego mieszanie (do przodu) deklaracji klas i struktur może w rzeczywistości prowadzić do trudnych do zrozumienia problemów z łączeniem!
MFH

1
  • . W klasach wszyscy członkowie są domyślnie prywatni, ale w strukturze członkowie są domyślnie publiczni.

    1. Nie ma takiego terminu jak konstruktor i destruktor dla struktur, ale kompilator klas tworzy domyślne, jeśli nie podasz.

    2. Rozmiar pustej struktury wynosi 0 bajtów, ponieważ rozmiar pustej klasy to 1 bajt Domyślny typ dostępu do struktury jest publiczny. Strukturę należy zwykle stosować do grupowania danych.

    Domyślny typ dostępu do klasy to prywatny, a domyślny tryb dziedziczenia to prywatny. Do grupowania danych i metod, które działają na tych danych, należy użyć klasy.

    Krótko mówiąc, konwencja polega na użyciu struktury, gdy celem jest grupowanie danych, i klas, gdy potrzebujemy abstrakcji danych i być może dziedziczenia.

    W C ++ struktury i klasy są przekazywane według wartości, chyba że jawnie odznaczone. W innych językach klasy i struktury mogą mieć odrębną semantykę - tj. obiekty (instancje klas) mogą być przekazywane przez odniesienie, a struktury mogą być przekazywane przez wartość. Uwaga: istnieją komentarze związane z tym pytaniem. Zobacz stronę dyskusji, aby dodać do rozmowy.


3
„2. Wielkość pustej struktury wynosi 0 bajtów, ponieważ klasa pustej wielkości to 1 bajt”. Fałszywe. Właśnie testowałem g++. Być może myślisz o optymalizacji pustej bazy, ale dotyczy to również obu.
cdunn2001

1
Nie prawda. W C ++ rozmiar pustej struktury wynosi 1. W C pusta struktura jest niedozwolona. GCC zezwala na puste struktury w C jako rozszerzenie kompilatora, a taka struktura ma rozmiar 0.
Johan Råde

Ta odpowiedź jest zła. Oprócz wielkości, część konstruktora / destruktora jest również niedokładna: struktury mogą dobrze mieć konstruktory i destruktory. W rzeczywistości structtworzy pełnoprawne klasy w C ++.
melpomene

1

Choć sugerowane przez inne odpowiedzi, nie jest wyraźnie wymienione - że struktury są kompatybilne z C, w zależności od użycia; klasy nie są.

Oznacza to, że jeśli piszesz nagłówek, który chcesz być kompatybilny z C, nie masz innej opcji niż struct (która w świecie C nie może mieć funkcji, ale może mieć wskaźniki funkcji).


-1

Możesz wziąć to pod uwagę w celu uzyskania wskazówek, kiedy wybrać strukturę lub klasę, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

√ UWAŻAJ zdefiniowanie struktury zamiast klasy, jeśli instancje tego typu są małe i zwykle krótkotrwałe lub są zwykle osadzone w innych obiektach.

X UNIKAJ definiowania struktury, chyba że typ ma wszystkie następujące cechy:

Logicznie reprezentuje pojedynczą wartość, podobną do typów pierwotnych (int, double itp.).

Ma rozmiar instancji poniżej 16 bajtów.

Jest niezmienny.

Nie będzie trzeba go często zapakować.


To dotyczy .NET / C #, a nie C ++.
melpomene

-2

Klasa ma znaczenie tylko w kontekście inżynierii oprogramowania. W kontekście struktur danych i algorytmów klasa i struktura nie różnią się tak bardzo. Nie ma żadnych ograniczeń, do których należy odwoływać się do członka klasy.

Opracowując duży projekt z mnóstwem ludzi bez klasy, możesz w końcu uzyskać skomplikowany kod, ponieważ wszyscy używają dowolnych funkcji i danych. Klasa zapewnia kontrolę uprawnień i elementy nieodłączne w celu usprawnienia oddzielania i ponownego wykorzystywania kodów.

Jeśli przeczytasz niektóre zasady inżynierii oprogramowania, przekonasz się, że większości standardów nie da się łatwo wdrożyć bez klasy. na przykład: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

Przy okazji, gdy struct przydziela pęknięcie pamięci i zawiera kilka zmiennych, zmienne typu wartości wskazują, że wartości są osadzone w miejscu, w którym przydzielona jest struktura. W przeciwieństwie do tego, wartości zmiennych typu referencyjnego są zewnętrzne i referencyjne za pomocą wskaźnika, który jest również osadzony w miejscu, w którym jest przydzielony struct.


Ta odpowiedź nie dotyczy C ++. W C ++ structdeklaruje klasy (w tym kontrolę uprawnień, dziedziczenie itp.).
melpomene

-3

Różnica między słowami kluczowymi struct i class w C ++ polega na tym, że gdy nie ma określonego specyfikatora dla określonego typu danych złożonych, wówczas domyślnie struct lub union są publicznymi słowami kluczowymi, które jedynie rozważają ukrywanie danych, ale klasa jest prywatnym słowem kluczowym, które rozważa ukrywanie programu kody lub dane. Zawsze niektórzy programiści używają struct dla danych i klasy dla samego kodu. Aby uzyskać więcej informacji, skontaktuj się z innymi źródłami.


OP wspomniała już, że structczłonkowie są domyślnie publiczni, a w zaakceptowanej odpowiedzi z 2009 r. Wspomniano o dziedziczeniu. Po co pisać kolejną odpowiedź, która nie dodaje żadnych nowych informacji 4 lata później?
melpomene

-3

Ze wszystkich tych czynników można wywnioskować, że klasa koncepcyjna doskonale nadaje się do przedstawiania obiektów świata rzeczywistego, a nie „struktur”. W dużej mierze dlatego, że koncepcje OOP stosowane w klasie są bardzo praktyczne w wyjaśnianiu scenariuszy ze świata rzeczywistego, dlatego łatwiej je połączyć z rzeczywistością. Na przykład domyślne dziedziczenie jest jawne dla struktur, ale jeśli zastosujemy tę regułę w świecie rzeczywistym, jest to śmieszne, ale w klasie domyślne dziedzictwo jest prywatne, co jest bardziej realistyczne.

W każdym razie, co muszę uzasadnić, to, że Klasa jest znacznie szerszą, stosowaną w świecie rzeczywistym koncepcją, podczas gdy Struktura jest prymitywnym Pojęciem o słabej organizacji wewnętrznej (Eventhough struct podąża za koncepcjami OOP, mają złe znaczenie)


1
W jaki sposób dziedziczenie prywatne jest „bardziej realistyczne”? Większość języków programowania nie ma nawet pojęcia dziedziczenia prywatnego.
melpomene

-3

Główną różnicą między słowem kluczowym struktura i klasa w ups jest to, że w strukturze nie występuje żadna publiczna i prywatna deklaracja członka, a funkcja danych i członek może być zdefiniowana jako publiczna, prywatna i chroniona.


Ta odpowiedź nie dotyczy C ++. W C ++ structdeklaruje klasy (w tym public/ private/ protected, dziedziczenie itp.).
melpomene

-3

** AKTUALIZACJA: ** Proszę zignorować tę odpowiedź. Nie brałem pod uwagę możliwości, że dla struktury wartość była niezainicjowana, ale akurat była równa 0. Nie ma różnicy inicjalizacji między strukturą a klasą.


Widzę inną różnicę między strukturami a klasami związaną z domyślną inicjalizacją.

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();
}

Uruchom ten kod i sprawdź myTester. Przekonasz się, że dla m_Foo, struct m_Foo.a została zainicjowana na 0, ale dla m_Bar klasa m_Bar.a jest niezainicjowana. Wydaje się więc, że istnieje różnica w tym, co robi domyślny konstruktor dla struktury vs. Widzę to w Visual Studio.


1
Jak ustaliłeś, że m_Foo.azostał zainicjowany? Co jeśli nie został zainicjowany i po prostu tak się stało 0?
melpomene

Nie zrobiłem tego. Mój błąd. To nie jest różnica między strukturą a klasą. Charakterystyka inicjalizacji jest taka sama.
Eric Hill

-4

Główną różnicą między struct i klasą jest to, że w struct można deklarować tylko zmienne danych różnych typów danych, podczas gdy w klasie można deklarować zmienne danych, funkcje składowe, a tym samym można manipulować zmiennymi danych za pomocą funkcji.

-> kolejną przydatną rzeczą, którą znajduję w klasie w porównaniu do struktury, jest to, że podczas wdrażania plików w programie, jeśli chcesz wykonywać niektóre operacje struktury w każdym nowym zestawie operacji, potrzebujesz osobnej funkcji i musisz przekazać obiekt struct po odczytaniu go z pliku, aby wykonać na nim pewne operacje. podczas gdy w klasie, jeśli wykonasz funkcję, która za każdym razem wykonuje operacje na danych potrzebnych ... to proste, wystarczy odczytać obiekt z pliku i wywołać funkcję ..

Ale to zależy od programisty, w jaki sposób on / ona uważa za odpowiednie ... według mnie wolę klasę za każdym razem tylko dlatego, że obsługuje OOP i to jest powód, dla którego jest implementowany w prawie wszystkich językach i jest to wspaniała cecha programowania wszech czasów; - )

I tak, najbardziej niezapomnianą różnicą, o której zapomniałem wspomnieć, jest to, że klasa obsługuje ukrywanie danych, a także obsługuje operacje wykonywane na wbudowanych typach danych, a struct nie!


1
W C ++ structmoże mieć funkcje
składowe

@chtz Dzięki ... Właśnie poznałem tę funkcję. Dziękuję bardzo. Jestem tylko początkującym, który nie jest tak ekspertem jak Ty, więc w przyszłości również potrzebuję porad od was :-)
Yug Rawal

a funkcja członka ma być rozumiana w szerszym znaczeniu. structmoże mieć konstruktory, funkcję członka i distruktor (ewentualnie wirtualny, ewentualnie prywatny, chroniony lub publiczny). Mogą dziedziczyć i być dziedziczone. więc właściwie ... wszystko, co klasa może mieć. typową konwencją jest deklarowanie za pomocą struct tego, co zadeklarowałbyś jako struct w C, i jako klasy, jeśli deklarujemy zmienną prywatną i chronioną, funkcje wirtualne, ctor i dtor i tak dalej. Ale to tylko konwencja, która nie jest egzekwowana przez język
Gian Paolo

-5

Znalazłem inną różnicę. jeśli nie zdefiniujesz konstruktora w klasie, kompilator go zdefiniuje. ale w strukturze, jeśli nie zdefiniujesz konstruktora, kompilator również nie zdefiniuje konstruktora. więc w niektórych przypadkach, że tak naprawdę nie potrzebujemy konstruktora, struct jest lepszym wyborem (wskazówka dotycząca wydajności). i przepraszam za mój zły angielski.


4
To nie jest prawda. Pod tym względem nie ma różnicy między klasą zdefiniowaną za pomocą structsłowa kluczowego a klasą zdefiniowaną za pomocą classsłowa kluczowego.
ymett

kiedy używam struktury bez konstruktora, uzyskuję lepszą prędkość niż klasa bez konstruktora.
Ali

@Ali Nie, nie masz.
Wyścigi lekkości na orbicie

-5

Klasy są typami odniesienia, a struktury są typami wartości.
Kiedy mówię, że Klasy są typami referencyjnymi,
zasadniczo zawierają adres zmiennych instancji.

Na przykład:

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.
}

W metodzie głównej
mogę utworzyć instancję tej klasy za pomocą nowego operatora, który przydziela pamięć dla tej klasy
i przechowuje jej adres podstawowy w zmiennej typu MyClass (_myClassObject2).

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

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

W powyższym programie MyClass _myClassObject2 = _myClassObject1; instrukcja wskazuje, że obie zmienne typu MyClass

  1. myClassObject1
  2. myClassObject2

i wskaże tę samą lokalizację pamięci.
Zasadniczo przypisuje tę samą lokalizację pamięci do innej zmiennej tego samego typu.

Więc jeśli jakiekolwiek zmiany, które wprowadzimy w jednym z obiektów typu MyClass, będą miały wpływ na inny
ponieważ oba wskazują na tę samą lokalizację pamięci.

„_myClassObject1.DataMember = 10;” w tym wierszu oba elementy danych obiektu będą zawierać wartość 10.
„_myClassObject2.DataMember = 20;” w tym wierszu zarówno element danych obiektu będzie miał wartość 20. W
końcu, uzyskujemy dostęp do członków danych obiektu przez wskaźniki.

W przeciwieństwie do klas, struktury są typami wartości. Na przykład:

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;
}

W powyższym programie
utworzenie instancji obiektu typu MyStructure przy użyciu nowego operatora i
zapisanie adresu w zmiennej _myStructObject typu MyStructure i
przypisanie wartości 10 członowi danych struktury za pomocą „_myStructObject1.DataMember = 10”.

W następnym wierszu
deklaruję inną zmienną _myStructObject2 typu MyStructure i przypisuję do niej _myStructObject1.
Tutaj kompilator .NET C # tworzy kolejną kopię obiektu _myStructureObject1 i
przypisuje tę lokalizację pamięci do zmiennej MyStructure _myStructObject2.

Zatem wszelkie zmiany, które wprowadzimy w _myStructObject1, nigdy nie będą miały wpływu na inną zmienną _myStructObject2 typu MyStructrue.
Dlatego mówimy, że struktury są typami wartości.

Zatem bezpośrednią klasą podstawową dla klasy jest Object, a bezpośrednią klasą podstawową dla Structure jest ValueType, który dziedziczy z Object.
Klasy będą wspierać dziedziczenie, podczas gdy struktury nie.

Jak to mówimy?
A jaki jest tego powód?
Odpowiedź brzmi: klasy.

Może być abstrakcyjny, zapieczętowany, statyczny i częściowy i nie może być prywatny, chroniony i chroniony wewnętrznie.


4
Myślę, że to próbuje odpowiedzieć na pytanie dla c #? Pytanie dotyczy c ++, a to czyni tę odpowiedź niedokładną, prawda?
smw

@smw absolutnie napisał swój przykładowy kod w języku C # i przyszedłem tutaj, aby sprawdzić, czy nie ma różnicy w przekazywaniu parametrów między C ++ structa class. Nikt tutaj nie wspomniał o tym ani o całej sieci. Więc nie sądzę, że dotyczy to również C ++.
John,

To nie jest nawet prawidłowy kod C # - wszystkie słowa kluczowe są nieprawidłowe. „Publiczne”, „Statyczne”, „Int” i „Klasa” nie powinny być pisane wielkimi literami i powinny być „struct”, a nie „Structure”. Opis jest głównie poprawny dla C # (chociaż struktury nadal mogą dziedziczyć interfejsy, ale nie inne struktury), ale nie odpowiada na pytanie, ponieważ dotyczyło C ++ ...
Darrel Hoffman

2
Ta odpowiedź jest kompletnym nonsensem. Używa dziwnej kombinacji Visual Basic i C # w swoich przykładach kodu, a całe „Klasy są typami referencyjnymi, a struktury są typami wartości” ... rzecz dotyczy tylko .NET (tj. C #), a nie C ++. Jesteś w niewłaściwym pokoju, stary. Oto miejsce, do którego należysz: stackoverflow.com/questions/13049
TheFlash,

Ale ta odpowiedź wskazuje, że to samo dotyczy C (++), że struktury są używane jak typy wartości. int a = 3; int b = a;i podobneMyStruct a=MyStruct("data"); MyStruct b = a;
luckydonald

-8

Istnieją 3 podstawowe różnice między strukturą a klasą

Pamięć 1St jest zarezerwowana dla struktury w pamięci stosu (która jest bliska językowi programowania), niezależnie od tego, czy dla klasy w pamięci stosu są zarezerwowane tylko odniesienia, a rzeczywista pamięć jest zarezerwowana w pamięci sterty.

2Nd - Domyślnie struktura traktuje jako publiczną, czy klasa traktuje jako prywatną.

3Rd - nie można ponownie użyć kodu w strukturze, ale w klasie możemy ponownie użyć tego samego kodu w wielu przypadkach zwanych dziedziczeniem


2
Struktury C ++ obsługują metody dziedziczenia i metody abstrakcyjne. Struktura i klasa są przydzielane w ten sam sposób. Przydzielanie klasy na stercie, nawet jeśli nie są tworzone za pomocą „nowego”, nie ma sensu dla systemów osadzonych.
JCMS

2
# 1 jest również błędny. Stos jest używany, gdy deklarujesz coś tego typu jako zmienną lokalną, a sterta jest używana, gdy używasz „nowego” operatora.
Score_Under
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.