Kiedy należy używać klasy a struct w C++?

W jakich scenariuszach lepiej używać struct vs A class W C++?

Author: Tamir Vered, 2008-09-10

24 answers

Różnice pomiędzy a class i a struct W C++ polegają na tym, że struktury mają domyślne public członków i bazy, A klasy mają domyślne private członków i bazy. Zarówno klasy jak i struktury mogą mieć mieszankę public, protected I private Członkowie, mogą używać dziedziczenia i mogą mieć funkcje Członkowskie.

Zalecałbym używanie struktur jako zwykłych starych struktur danych bez żadnych cech podobnych do klas oraz używanie klas jako zagregowanych struktur danych z private danymi i funkcjami składowymi.

 642
Author: Commodore Jaeger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-30 06:23:37

Jak wszyscy zauważają, istnieją naprawdę tylko dwie rzeczywiste różnice językowe:

  • struct domyślnie dostęp publiczny i class domyślnie dostęp prywatny.
  • przy dziedziczeniu, struct domyślnie public dziedziczenie i class domyślnie private dziedziczenie. (Ironicznie, jak w przypadku tak wielu rzeczy w C++, domyślna wartość jest odwrotna: public dziedziczenie jest zdecydowanie bardziej powszechnym wyborem, ale ludzie rzadko deklarują struct s tylko po to, aby zaoszczędzić na wpisaniu "public" słowo kluczowe.
[[14]} ale prawdziwa różnica w praktyce polega na tym, że class/struct to deklaruje konstruktor/Destruktor i taki, który tego nie robi. istnieją pewne gwarancje dla typu" plain-old-data", które przestają obowiązywać po przejęciu konstrukcji klasy. Aby to rozróżnienie było jasne, Wiele osób celowo używa tylko struct s dla typów POD, a jeśli mają zamiar dodać jakiekolwiek metody, używają class es. Różnica między dwoma poniższymi fragmentami jest inna bez znaczenia:
class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(nawiasem mówiąc, Oto wątek z kilkoma dobrymi wyjaśnieniami na temat tego, co" Typ POD " właściwie oznacza: jakie są typy POD W C++?)

 178
Author: quark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:30

Istnieje wiele błędnych przekonań w istniejących odpowiedziach.

Zarówno class jak i struct deklarują klasę.

Tak, być może będziesz musiał zmienić swój dostęp modyfikując słowa kluczowe wewnątrz definicji klasy, w zależności od słowa kluczowego użytego do zadeklarowania klasy.

Ale, poza składnią, jedynym powodem wyboru jednego nad drugim jest konwencja / styl / preferencja.

Niektórzy lubią trzymać się słowa kluczowego struct dla klas bez funkcji członowych, ponieważ wynikowa definicja "wygląda jak" prosta struktura z C.

Podobnie niektórzy ludzie lubią używać słowa kluczowego class dla klas z funkcjami członkowskimi i danymi private, ponieważ na nich jest napisane "class" i dlatego wygląda jak przykłady z ich ulubionej książki o programowaniu obiektowym.

Rzeczywistość jest taka, że to zależy wyłącznie od Ciebie i Twojego zespołu, a to nie zrobi żadnej różnicy dla Twojego programu.

The następujące dwie klasy są absolutnie równoważne pod każdym względem z wyjątkiem ich nazwy: {]}

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Możesz nawet zmienić słowa kluczowe podczas redeclaringu:

class Foo;
struct Bar;

(chociaż niektóre Kompilatory emitują ostrzeżenie, gdy to zrobisz, zakładając, że prawdopodobnie nie zamierzałeś zrobić czegoś tak mylącego i dlatego powinieneś zostać poproszony o podwójne Sprawdzenie kodu.)

I następujące wyrażenia oceniają jako true:

std::is_class<Foo>::value
std::is_class<Bar>::value

Należy jednak pamiętać, że nie można przełączać słów kluczowych, gdy redefiniuje ; dzieje się tak tylko dlatego, że (zgodnie z regułą one-definition) duplikuje definicje klas między jednostkami tłumaczenia muszą "składać się z tej samej sekwencji tokenów". Oznacza to, że nie można nawet wymieniać const int member; z int const member; i nie ma to nic wspólnego z semantyką class lub struct.

 100
Author: Lightness Races in Orbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-15 12:39:25

Używam struktury zamiast klasy tylko wtedy, gdy deklaruję functora tuż przed użyciem go w wywołaniu funkcji i chcę zminimalizować składnię dla jasności. np.:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 
 50
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 19:18:58

From the C++ FAQ Lite :

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

Struct i klasa są inaczej funkcjonalnie równoważne.

Ok, dość tych piszczących, czystych gadek techno. Emocjonalnie, większość programistów robi silne rozróżnienie między klasą A struct. Struktura po prostu czuje się jak otwarty stos bitów z bardzo małą ilością na drodze do hermetyzacji 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ż jest to konotacja, którą ma już większość ludzi, powinieneś prawdopodobnie użyć słowa kluczowego struct, jeśli masz klasę, która ma bardzo mało metod i ma publiczne dane (takie rzeczy istnieją w dobrze zaprojektowanych systemach!), ale inaczej powinieneś użyć słowa kluczowego class.

 31
Author: Tal Pressman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-10 09:19:07

Jednym z miejsc, gdzie struktura była dla mnie pomocna, jest to, że mam system, który odbiera wiadomości o stałym formacie (powiedzmy, port szeregowy) z innego systemu. Strumień bajtów można wrzucić do struktury definiującej pola, a następnie łatwo uzyskać do nich dostęp.

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

Oczywiście jest to to samo, co w C, ale uważam, że konieczność dekodowania wiadomości do klasy zwykle nie jest tego warta.

 20
Author: mbyrne215,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 11:15:02

Możesz użyć "struct" w C++, jeśli piszesz bibliotekę, której wewnętrznymi elementami są C++ , ale API może być wywołane przez kod C lub C++. Po prostu tworzysz pojedynczy nagłówek, który zawiera struktury i globalne funkcje API, które wystawiasz zarówno na kod C, jak i C++ w następujący sposób:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

Następnie możesz napisać funkcję bar () w pliku C++ używając kodu C++ i uczynić ją możliwą do wywołania z C, a oba światy mogą współdzielić dane poprzez zadeklarowane struktury. C++ , ale jest to uproszczony przykład.

 15
Author: Adisak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-20 21:53:42

Jak każdy mówi, jedyną prawdziwą różnicą jest domyślny dostęp. Ale szczególnie używam struct, gdy nie chcę żadnej enkapsulacji z prostą klasą danych, nawet jeśli zaimplementuję jakieś metody pomocnicze. Na przykład, gdy potrzebuję czegoś takiego:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};
 11
Author: ogoid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 16:13:06

Structs (PODs , bardziej ogólnie) są przydatne, gdy dostarczasz interfejs zgodny z c z implementacją C++, ponieważ są przenośne ponad granicami języka i formatami linkerów.

Jeśli nie jest to dla Ciebie problemem, to przypuszczam, że użycie "struct" zamiast "class" jest dobrym komunikatorem intencji (jak powiedział @ZeroSignal powyżej). Struktury mają również bardziej przewidywalną semantykę kopiowania, więc są przydatne dla danych, które zamierzasz zapisać na nośnikach zewnętrznych lub wysłać do nich drut.

Struktury są również przydatne do różnych zadań metaprogramowania, takich jak szablony cech, które po prostu ujawniają kilka zależnych typów:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

...Ale tak naprawdę jest to po prostu wykorzystanie domyślnego poziomu ochrony struct jako publicznego...

 8
Author: argv0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-31 11:51:44

Dla C++, naprawdę nie ma dużej różnicy między strukturami a klasami. Główną różnicą funkcjonalną jest to, że elementy struktury są domyślnie publiczne, podczas gdy są domyślnie prywatne w klasach. W przeciwnym razie, jeśli chodzi o język, są one równoważne.

To powiedziawszy, zwykle używam struktur w C++, tak jak w C#, podobnie jak Brian powiedział. Struktury są prostymi kontenerami danych, natomiast klasy są używane dla obiektów, które oprócz trzymam się tego.

 7
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 16:36:00

Odpowiadając na moje własne pytanie (bezwstydnie), jak już wspomniano, uprawnienia dostępu są jedyną różnicą między nimi w C++.

Zwykle używam struktury tylko do przechowywania danych. Pozwolę mu uzyskać kilka pomocniczych funkcji, jeśli ułatwi to pracę z danymi. Jednak gdy tylko dane będą wymagały kontroli przepływu (tj. getterów / setterów, które utrzymują lub chronią stan wewnętrzny) lub zaczną korzystać z większej funkcjonalności( w zasadzie bardziej obiektowej), zostaną "uaktualnione" do Klasa, aby lepiej komunikować intencje.

 5
Author: Alan Hinchcliffe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 16:50:18

To prawie to samo. Dzięki magii C++ struktura może posiadać funkcje, używać dziedziczenia, tworzyć za pomocą " new " i tak dalej, tak jak klasa

Jedyna różnica polega na tym, że Klasa zaczyna się od prywatnych praw dostępu, podczas gdy struktura zaczyna się od publicznego. Jest to zachowanie kompatybilności wstecznej z C.

W praktyce zawsze używałem struktur jako posiadaczy danych, a klas jako obiektów.

 4
Author: enigmatic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 16:36:17

Klasa.

Członkowie klasy są domyślnie prywatni.

class test_one {
    int main_one();
};

Jest równoważne

class test_one {
  private:
    int main_one();
};

Więc jeśli spróbujesz

int two = one.main_one();

Otrzymamy błąd: main_one is private ponieważ jest on niedostępny. Możemy rozwiąż go, inicjując go przez podanie jego publicznego ie

class test_one {
  public:
    int main_one();
};

Struct.

Struktura jest klasą, w której członkowie są domyślnie publiczni.

struct test_one {
    int main_one;
};

Oznacza main_one jest prywatnym ie

class test_one {
  public:
    int main_one;
};

Używam structs dla struktur danych, gdzie Członkowie mogą przyjmować każda wartość, to tak będzie łatwiej.

 3
Author: Frrank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-12 00:09:18

To to samo z różnymi ustawieniami domyślnymi (domyślnie private dla class i public dla struct), więc teoretycznie są całkowicie wymienne.

Więc, jeśli chcę po prostu spakować jakieś informacje, aby się poruszać, używam struktury, nawet jeśli umieszczę tam kilka metod (ale nie wiele). Jeśli jest to w większości nieprzejrzysta rzecz, gdzie główne użycie byłoby za pomocą metod, a nie bezpośrednio do członków danych, używam pełnej klasy.

 2
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 03:49:00

Struktury domyślnie mają dostęp publiczny, a klasy mają dostęp prywatny.

Osobiście używam struktur do przesyłania danych lub jako obiektów wartości. Gdy używane jako takie deklaruję wszystkie członkowie jako const, aby zapobiec modyfikacji przez inny kod.

 2
Author: anio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 03:51:02

Technicznie oba są takie same w C++ - na przykład możliwe jest, że struktura ma przeciążone operatory itp.

Jednakże:

Używam struktur, gdy chcę przekazywać informacje wielu typów jednocześnie Używam klas, gdy mam do czynienia z obiektem "funkcjonalnym".

Mam nadzieję, że to pomoże.
#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

Na przykład, zwracam studenta struct w get...() 00: 00, 20 sie 2011 (CEST)

 1
Author: Maciek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 04:42:17

Kiedy wybrać struct a kiedy używać klasy w C++?

Używam struct Kiedy definiuję functors i POD. W przeciwnym razie używam class.

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
    bool operator()(int first, int second)
    { return first < second; }
};

class mycompare : public std::binary_function<int, int, bool>
{
public:
    bool operator()(int first, int second)
    { return first < second; }
};
 1
Author: AraK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 20:40:22

Używam struktur, gdy muszę utworzyć pod type lub functor.

 1
Author: ivan.ukr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-15 09:30:25

Zaletą struct nad class jest to, że zapisuje jedną linijkę kodu, jeśli jest zgodna z "first public members, then private". W tym świetle słowo kluczowe class wydaje mi się bezużyteczne.

Oto kolejny powód używania tylko struct i nigdy class. Niektóre wytyczne dotyczące stylu kodu dla C++ sugerują użycie małych liter dla makr funkcji, uzasadniając to tym, że gdy makro zostanie przekonwertowane na funkcję wbudowaną, nazwa nie powinna być zmieniana. Ja też. Masz swoją ładną strukturę w stylu C i pewnego dnia dowiesz się, że musisz dodać konstruktor lub jakąś wygodną metodę. Zmieniasz na class? Wszędzie?

Rozróżnianie pomiędzy struct s I classes jest po prostu zbyt kłopotliwe, wchodzenie w sposób robienia tego, co powinniśmy robić-programowania. Podobnie jak wiele problemów C++, wynika to z silnego pragnienia wstecznej kompatybilności.

 1
Author: Vorac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-10 09:49:59

Używam struct tylko wtedy, gdy muszę przechowywać pewne dane bez żadnych powiązanych z nimi funkcji Członkowskich (aby operować na danych członkowskich) i uzyskać bezpośredni dostęp do zmiennych danych.

Np: Odczyt / Zapis danych z plików i strumieni gniazd itp. Przekazywanie argumentów funkcji w strukturze, w której argumentów funkcji jest zbyt wiele, a składnia funkcji wygląda na zbyt długą.

Technicznie nie ma dużej różnicy między klasą A struture z wyjątkiem domyślnej dostępności. Więcej na to zależy na styl programowania jak go używać.

 0
Author: harik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 04:29:10

Polecam nie mieszać structs I classes.

Jak zauważyli inni

  • oba są równoważne poza domyślną widocznością
  • mogą być powody, aby być zmuszeni do korzystania z jednego lub drugiego z jakiegokolwiek powodu

Jeśli nie jesteś zmuszony, idź tylko struct s lub tylko class es, ponieważ chroni cię to przed cryptic linker problemy z zero kosztów.

If you forward declare sth. jak class X; i później zdefiniuj go jako struct X { ... } może działać na niektórych linkerach (np. g++) i może zawieść na innych (np. MSVC), więc znajdziesz się w developer hell. Ponieważ nie ma powodu, aby mieszać struct i class, Dlaczego należy bardziej skomplikować myśli i dbać o to, czy to coś było class Czy struct?

 0
Author: pasbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 11:05:27

Myślałem, że struktury są przeznaczone jako struktura danych (jak tablica informacji o wielu typach danych) , a klasy są przeznaczone do pakowania kodu (jak Kolekcje podprogramów i funkcji)..

:(

 -3
Author: GaiusSensei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-28 04:07:59

Nigdy nie używam "struct" w C++.

Nigdy nie wyobrażam sobie scenariusza, w którym użyłbyś struktury, gdy chcesz prywatnych członków, chyba że celowo próbujesz być mylący.

Wydaje się, że używanie struktur jest bardziej składniowym wskazaniem, jak dane będą używane, ale wolałbym po prostu utworzyć klasę i spróbować to wyraźnie wyrazić w nazwie klasy lub poprzez komentarze.

Np.

class PublicInputData {
    //data members
 };
 -5
Author: Baltimark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 18:02:25

Funkcje dostępu nie są jedyną różnicą między strukturami a klasami. Struktura jest lepsza dla typów POD (Plain Old Data), ponieważ jest łatwiejsza do zarządzania dla kompilatora i programisty. Dla początkujących, którzy nie używają programowania obiektowego, użycie struktury jest w porządku.

 -6
Author: Eitan Myron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-21 18:58:36