Struktura C / C ++ a klasa

108

Po skończeniu mojej klasy C ++ wydawało mi się, że struktury / klasy są praktycznie identyczne, z wyjątkiem kilku drobnych różnic.

Nigdy wcześniej nie programowałem w C; ale wiem, że ma struktury. Czy w C można dziedziczyć inne struktury i ustawić modyfikator public / private?

Jeśli możesz to zrobić w zwykłym C, dlaczego na świecie potrzebujemy C ++? Co sprawia, że ​​klasy różnią się od struktury?


źródło
możliwy zduplikowany stackoverflow.com/questions/54585/ ...
gonzobrains

Odpowiedzi:

146

W C ++ struktury i klasy są prawie takie same; jedyną różnicą jest to, że tam, gdzie modyfikatory dostępu (dla zmiennych składowych, metod i klas bazowych) w klasach są domyślnie prywatne, modyfikatory dostępu w strukturach domyślnie mają wartość public.

Jednak w C struktura jest po prostu zbiorczym zbiorem (publicznych) danych i nie ma innych cech klasowych: żadnych metod, konstruktora, klas bazowych itp. Chociaż C ++ odziedziczył słowo kluczowe, rozszerzył semantykę. (To jest jednak powód, dla którego w strukturach domyślnie rzeczy są publiczne - struktura napisana jak struktura w C zachowuje się jak jedna).

Chociaż możliwe jest sfałszowanie niektórych OOP w C - na przykład definiowanie funkcji, które wszystkie przyjmują wskaźnik do struktury jako pierwszy parametr lub czasami wymuszanie przekształcenia struktur z tymi samymi pierwszymi polami jako „podklasy / nadklasy” - zawsze przykręcone i tak naprawdę nie jest częścią języka.

Antal Spector-Zabusky
źródło
Z perspektywy OOP faceci z .Net zdefiniowali to w ten sposób ✓ ROZWAŻ zdefiniowanie struktury zamiast klasy, jeśli instancje tego typu są małe i zwykle krótkotrwałe lub są często osadzone w innych obiektach. X UNIKAJ definiowania struktury, chyba że typ ma wszystkie z następujących cech: 1. Logicznie reprezentuje pojedynczą wartość, podobnie jak typy pierwotne (int, double itp.). 2. Ma rozmiar instancji poniżej 16 bajtów. 3. Jest niezmienna.
Abhijeet
5
@Abhijeet To jest różnica między strukturami i klasami w C #, ale jest to po prostu nieistotne dla C ++, a tym bardziej dla C. W C # klasy i struktury są w rzeczywistości różne; nie tak w C ++, a C ma tylko struktury bez OO.
Antal Spector-Zabusky
nie byłoby lepiej zachować tę samą semantykę C w strukturze C ++? a kiedy wymagane jest użycie „struktury w języku C ++” po prostu użyj klasy? Nigdy nie odniosłem korzyści z posiadania „rozszerzonej” struktury w C ++ w porównaniu z C. Lubię nadal używać struktury, tak jak została zaprojektowana w C, w przeciwnym razie używam klasy, z dozwolonymi wyjątkami.
Raffaello
15

Poza tym różnice w dostępie domyślnym (publiczny / prywatny), nie ma różnicy.

Jednak niektóre sklepy, które kodują w C i C ++, będą używać „class / struct” do wskazania tego, co może być używane w C i C ++ (struct), a które są tylko w C ++ (class). Innymi słowy, w tym stylu wszystkie struktury muszą współpracować z C i C ++. Dlatego właśnie dawno temu istniała różnica, kiedy C ++ było jeszcze znane jako „C z klasami”.

Zwróć uwagę, że związki C działają z C ++, ale nie na odwrót. Na przykład

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

I podobnie

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

działa tylko w C

Lance Diduck
źródło
9
Używanie słów kluczowych cpp w kodzie c, a następnie twierdzenie, że nie jest on zgodny z cpp, jest raczej głupie
Dani
7

Zamierzam dodać do istniejących odpowiedzi, ponieważ nowoczesny C ++ jest teraz czymś, a oficjalne podstawowe wytyczne zostały stworzone, aby pomóc w takich pytaniach.

Oto odpowiednia sekcja z wytycznych:

C.2: Użyj klasy, jeśli klasa ma niezmiennik; użyj struct, jeśli członkowie danych mogą się zmieniać niezależnie

Niezmiennik jest logicznym warunkiem dla elementów członkowskich obiektu, który konstruktor musi ustalić, aby mogły przyjąć publiczne funkcje składowe. Po ustaleniu niezmiennika (zwykle przez konstruktora) można wywołać każdą funkcję składową dla obiektu. Niezmiennik można podać nieformalnie (np. W komentarzu) lub bardziej formalnie za pomocą Oczekiwania.

Jeśli wszyscy członkowie danych mogą się zmieniać niezależnie od siebie, niezmienność nie jest możliwa.

Jeśli klasa ma jakieś prywatne dane, użytkownik nie może całkowicie zainicjować obiektu bez użycia konstruktora. W związku z tym osoba definiująca klasę zapewni konstruktor i musi określić jego znaczenie. W praktyce oznacza to potrzebę zdefiniowania niezmiennika.

Egzekwowanie

Poszukaj struktur ze wszystkimi danymi prywatnymi i klas z publicznymi członkami.

Podane przykłady kodu:

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

Classe działają dobrze w przypadku członków, którzy są na przykład pochodzący od siebie nawzajem lub ze sobą powiązani. Mogą również pomóc w sprawdzaniu poprawności podczas tworzenia instancji. Structdobrze sprawdzają się w przypadku posiadania „worków danych”, w których tak naprawdę nic specjalnego się nie dzieje, ale logicznie rzecz biorąc, grupy członków mają sens.

Z tego wynika, że classistnieją es do obsługi hermetyzacji i innych pokrewnych koncepcji kodowania, do których structpo prostu nie są zbyt przydatne.

Dave
źródło
Kolejną kwestią jest przenośność. structs są najbardziej przenośne. Mogą być używane przez C lub C ++ albo tam iz powrotem. Można je również rozpakować structna przykład w Pythonie za pomocą modułu. Jeśli twoje priorytety projekt jest zgodny z innych języków, interfejsów lub systemów, wolą structsię class. Preferuj sprawy ściśle programowe class.
Dave,
6

Nie można definiować funkcji składowych ani wyprowadzać struktur od siebie w C.

Ponadto C ++ to nie tylko C + „struktury pochodne”. Szablony, odwołania, przestrzenie nazw zdefiniowane przez użytkownika i przeciążenie operatorów nie istnieją w C.

Johannes Schaub - litb
źródło
Wiem, że szablony itp. Nie istnieją w C, ale nie byłem świadomy powerstruktur w C. Czyli C ++ używa struktur tylko do „wstecznie” kompatybilności z C?
4
Tylko dla wstecznej kompatybilności? Z praktycznego punktu widzenia prawdopodobnie coś w tym jest, ale rozróżnienie może być sygnałem intencji: gdy używam, structmam na myśli w dużej mierze pasywny typ POD.
dmckee --- kociak ex-moderator
@dmckee: Co jest warte, większość funktorów STL (tj. std::less) jest definiowanych jako struktury, a nie klasy.
Billy ONeal
1
C ++ nie jest w pełni kompatybilny z C. Można powiedzieć, że słowo kluczowe struct jest przystosowaniem dla programistów C. Podoba mi się słowo kluczowe struct dla klas, które po prostu przechowują dane w uporządkowany sposób, ale same nie zapewniają (zbyt wiele) logiki.
ypnos
@ypnos: Zobacz mój ostatni komentarz. Jedyna różnica między nimi polega na tym, że jeden z członków jest domyślnie publiczny, a drugi jest domyślnie prywatny.
Billy ONeal
3

Jeszcze jedna różnica w C ++, kiedy dziedziczysz klasę ze struktury bez żadnego specyfikatora dostępu, staje się ona dziedziczeniem publicznym, podczas gdy w przypadku klasy jest to dziedziczenie prywatne.

MarsRover
źródło
1

C ++ używa struktur głównie do 1) wstecznej zgodności z typami C i 2) POD. Struktury C nie mają metod, dziedziczenia ani widoczności.

Chris Hafey
źródło
2
Co jest warte, większość funktorów STL (tj. std::less) Jest definiowanych jako struktury, a nie klasy.
Billy ONeal
3
Zauważ, że struktury C ++ mają metody, dziedziczenie i widoczność.
robertwb
struktura c może jednak zawierać wskaźnik funkcji jako typ (* addr) (params);
Błąd