Struct Konstruktor
-
struct Bla{ //public: //ist implizit da int a; //kann man drauf zugreifen, ist public public: int b; //kann man drauf zugreifen, ist public private: int c; //kann man nicht drauf zugreifen, ist private }; class Blup{ //private: //ist implizit da int a; //kann man nicht drauf zugreifen, ist private public: int b; //kann man drauf zugreifen, ist public private: int c; //kann man nicht drauf zugreifen, ist private };
-
Skeptar schrieb:
...
Du hast etwas falsch verstanden...
Wenn du kein public/private angibst, so ist bei einer class alles automatisch private, bei einer struct alles public:
class foo { int a; // <-- private }; struct foo { int a; // <-- public };
Von außen kann man nur auf public-Member zugreifen, alle Member können im Regelfall (Ausnahme ist z.B. nicht-public Vererbung, aber das ist sehr selten) aber auf alle Teile zugreifen.
-
Skeptar schrieb:
Bei einer "class" kann man die in dem "private" eingetragenen Bereich nur mit einer Funktion aus dem "public" Bereich ansprechen?
Von ausserhalb der Klasse: ja.
Skeptar schrieb:
Und bei dem "struct" kann man dirket ohne Funktion auf die Variablen im "private" Bereich zugreifen?
Nein, struct verhält sich da genau wie class.
Du solltest die Antworten noch einmal sorgfältig lesen.
-
Okay.
Aber ich finde es etwas unnötig 2 verschiedene "Bausteine", und im wesentlichen habe die beiden die gleiche Funktion.Gut das werde ich mir das noch einmal durchlesen
-
Skeptar schrieb:
Aber ich finde es etwas unnötig 2 verschiedene "Bausteine", und im wesentlichen habe die beiden die gleiche Funktion.
Ist historisch bedingt und hat auch etwas mit der (weitgehenden) Kompatibilität zu C zu tun. Wobei man für C-kompatible structs noch ein paar Dinge mehr berücksichtigen muss (wobei das nur relevant ist, wenn du eine C-Schnittstelle brauchst).
-
Ich find's auch ein bisschen komisch. Aber bei C++ gibt's viel was komisch ist.
Gebraucht hätte man es auch nicht. C++ hätte das neue Keyword "class" einfach weglassen können. Viel öfter "private:" schreiben müsste man dadurch auch nicht. Die meisten C++-ler fangen sowieso mit den Public-Funktionen an, da würde man sich sogar noch ein "public:" sparen. Und bei den Basisklassen is auch meist public angesagt - private Basisklassen sind ja eher ein Sonderfall.
Vermutlich konnte sich Stroustrup einfach nicht zurückhalten -- ohne das Keyword "class" wäre C++ ja viel weniger "objektig". Und da objektig == gut...
-
Wenns schon 2 Varianten gibt, kann man sie für semantische Unterschiede einsetzen. Ich nehme
struct
meist für kleine Datenbündel oder Funktoren undclass
für Klassen mit Kapselung.hustbaer schrieb:
Aber bei C++ gibt's viel was komisch ist.
Es gibt vor allem für alles mehrere Ansätze. Für den einzig wahren Weg gibts gewisse andere Programmiersprachen
P.S.: Tritt jemand den Verfechtern von
enum struct
stattenum class
bei?
-
@Nexus
Die meisten anderen Sachen, wo man in C++ mehrere Möglichkeiten hat, sind aber recht deutlich anders (z.B.FILE*
vs.fstream
,#define
vs.static cosnt
vs.enum
). Oder exakt gleich bis auf die Schreibweise (int
vs.signed int
).Aber
struct
vs.class
... pfuh. Das ist so "fast aber nicht ganz gleich". Schon etwas eigen.
-
class vs typename als Templateparameter ist genauso, wenn nicht sogar noch subtiler.
-
Öhm.
Ich würde nicht sagen dass das das selbe ist.class
vs.typename
bei Templateparameters ist exakt das selbe von der Bedeutung her. "Subtil" ist dabei höchstens die Frage wo man statttypename
auchclass
schreiben kann. Aber dort wo manclass
statttypename
schreiben kann, bewirkt es exakt das selbe. Es sei denn ich hätte da irgend eine bekloppte C++11/14 Neuerung verpennt.Also eher das selbe wie
signed int
vs.int
.BTW:
char
vs.signed char
vs.unsigned char
ist auch so ne komische C++ Sache.
-
Nexus schrieb:
P.S.: Tritt jemand den Verfechtern von
enum struct
stattenum class
bei?Wenns schon 2 Varianten gibt, kann man sie für semantische Unterschiede einsetzen. Ich nehme
struct
meist für kleine Datenbündel oder Funktoren undclass
für Klassen mit Kapselung.So ist es bei mir und bei vielen anderen auch. Das sollte man nicht dazu missbrauchen, weniger
private
oderpublic
zu schreiben.
-
Trotzdem hätte man sich ohne Probleme auf
typename
für Template-Typparameter festlegen können. Ist ja nicht so, dassclass
irgendeinen Vorteil (vielleicht abgesehen von Kompatibilität in der Steinzeit) brächte. Sogar der ursprüngliche Punkt, dass Template-Templatesclass
erfordern, weil es sich um Klassen handeln muss, dürfte mit Template Aliases dahin sein. Was bleibt, ist ein weiteres Relikt, an dessen Ursprung sich niemand mehr erinnern kann. Wie<iosfwd>
neulich. Oder in nicht allzu ferner Zukunft Disketten als Speichern-Icon.Es gibt aber genügend solche fast gleichen Sachen. Und das kann man keineswegs nur auf C oder antikes C++ schieben; auch C++11 schreckt nicht davor zurück, subtilste Falltüren einzubauen:
decltype
mit und ohne Zusatzklammern,int&&
vsT&&
als Parameter. Scheint tief in der Sprachphilosophie verankert zu sein.Auch von mehreren Schreibweisen für genau das Gleiche gibts einige zunächst unintuitive Sachen:
int*
undint x[3]
als Parameter,&func
undfunc
für Funktionszeiger, Dutzendetypedef
s für Ganzzahlen in der Standardbibliothek. Alles auch mehr verwirrend als nützlich.Und vergessen wir nicht gleiche Schreibweise für Verschiedenes, an vorderster Front Most Vexing Parse. Oder die "Uniform Initialization", erst mit ihr kann die Schreibweise
X x = {args}
einheitlicherweise sowohl Aggregat-Initialisierung, Konstruktoraufruf mit mehreren Parametern als auch Initializer-List bedeuten
-
dürfte mit Template Aliases dahin sein
Alias-Templates. Das ist dasselbe Missverständnis wie "Template Klasse".
int&&
vsT&&
als ParameterNö! Das ist überhaupt nicht subtil.
int&&
ist ein feststehender Typ, wohingegenT&&
- als Parameter - eine "Universal Reference" ist: Ein (ggf.) zu deduzierender Referenztyp. Es greift die reference-collapsing Regel. Es sind zwei von Grund auf verschiedene Dinge, ohne diese Regel wäre auch perfect forwarding nicht möglich.
Na gut, im Prinzip recht unintuitiv.erst mit ihr kann die Schreibweise X x = {args} einheitlicherweise sowohl Aggregat-Initialisierung, Konstruktoraufruf mit mehreren Parametern als auch Initializer-List bedeuten
Das nennt sich einheitlich list-initialization, nennen wir es auf Deutsch fortan Listeninitialisierung. Diese gliedert sich völlig natürlich auf in eine Aggregatinitialisierung für Aggregate und Konstruktoraufrufe auf: Letzteres ist immer ein Konstruktoraufruf, nur dass bei diesem Konstruktoraufruf Initialisierungslisten-Konstruktoren in der Overload Resolution bevorzugt werden. Je nach dem werden die Elemente anders interpretiert, die Semantik ist aber insgesamt intuitiv.
Dutzende typedefs für Ganzzahlen in der Standardbibliothek.
Kannst du genau sagen, was an
intmax_t
,uint64_t
,uint_fast64_t
usw. verwirrend ist? Schaut man sich einmal die Definition an, wird schnell klar, wofür das nützlich ist.So, ich gebe auf. Man kann C++ nicht verteidigen.
-
hustbaer schrieb:
Öhm.
Ich würde nicht sagen dass das das selbe ist.class
vs.typename
bei Templateparameters ist exakt das selbe von der Bedeutung her. "Subtil" ist dabei höchstens die Frage wo man statttypename
auchclass
schreiben kann. Aber dort wo manclass
statttypename
schreiben kann, bewirkt es exakt das selbe. Es sei denn ich hätte da irgend eine bekloppte C++11/14 Neuerung verpennt.Also eher das selbe wie
signed int
vs.int
.BTW:
char
vs.signed char
vs.unsigned char
ist auch so ne komische C++ Sache.Jetzt bin ich gerade verwiirt.
template <template <typename> class T> class foo;
Geht soweit ich weiß nicht mit typename...
-
Geht soweit ich weiß nicht mit typename...
Ja und? Was ist nun an hustbaers Beitrag verwirrend? Er sagt, wo man beide austauschen kann, sind sie identisch. Wo nicht, da nicht.