Hi,
auch wenn der Thread schon einen Monat alt ist, will ich doch nochmal versuchen ein wenig Licht in das Dunkel hier zu bringen.
int l=34;
Klasse Kl(5,&l);
Kl.i=53; funkioniert tadellos
Kl.*j=75; funktioniert nicht warum?
Du willst also den Wert von l aendern, indem du *j (der Speicher auf den j zeigt) auf 75 setzt, richtig? Dann musst du erst auf den Pointer zugreifen, und darauf dann den Sternchen Operator anwenden. Der Operator hat in dem Zusammenhang auch einen besonderen Namen, der faellt mir aber grade nicht ein (Adress-Operator oder so?). D.h. korrekt waere:
Einen .* operator gibt es IMHO nicht.
ABER: Bitte, bitte, verwende Klassen nicht einfach als bessere Struktur, sondern halte dich an vernuenftige OO Prinzipien, und mache keine member Variablen public, sondern verwende Getter und Setter Methoden falls auf die Variablen zugegriffen werden muss.
Sollte dies dein erster Kontakt mit Objekt Orientierter Programmierung sein, moechte ich stark davon abraten mit C++ zu beginnen, sondern wuerde eher empfehlen mit einer vernuenftig designten OO Sprache wie z.B. Java anzufangen (Python und Ruby sollen auch gut designt sein).
C++ macht einem so krasse Stilfehler einfach viel zu einfach.
Welche Vorteile bringt es eigentlich mit sich, wenn man Klassen als Zeiger Initialisiert, bzw. was ist der Unterschied zwischen:
Klasse K = new Klasse(5,&l); und
Klasse *pK = new Klasse(5,&l);
Wie von h2owasser schon ganz richtig angemerkt wurde, wird ersteres nicht funktionieren, aber du meintest vielleicht den Unterschied zwischen
Code:
Klasse K(5, &l); und
Klasse *pK = new Klasse(5,&l);
? [1]
Im ersten Fall instanziierst du die Klasse "Klasse". D.h. wenn der Block, in dem die Instanziierung stattgefunden hat, endet, wird der Speicher, der fuer dieses Objekt reserviert wurde, automatisch wieder freigegeben.
Du hast mit der Speicherverwaltung also nix am Hut.
Wenn du aber mit new neuen Speicher fuer das Objekt anforderst, wird der Speicher nicht automatisch freigegeben. Darum musst du dich selber kuemmern, sobald du das Objekt nicht mehr brauchst (s. delete). Das kann, insofern das nicht wirklich gewollt war, relativ leicht zu Memory Leaks fuehren.
Jetzt koennte man sich fragen, wofuer braucht man sowas? Ganz einfach, nehmen wir mal an wir haben eine Methode CreateInstance(), in der eine neue Instanz von Klasse A erzeugt werden soll:
Code:
class A
{
public:
A(int x) : m_x(x) {}
A CreateInstance()
{
A a(5);
return a;
}
int GetX() const
{
return m_x;
}
private:
int m_x;
};
int main()
{
A a(1);
A anew = a.CreateInstance();
int x = anew.GetX();
}
Ich hab das jetzt nur so ungetestet runtergeschrieben, aber wenn ich keinen Fehler gemacht habe, sollte das Programm kompilieren. Aber wenn du das jetzt versuchst auszufuehren, duerftest du eine Zugriffsverletzung kriegen. Warum?
Weil der Speicher von anew in main() bereits beim Ende von CreateInstance() wieder freigegeben wurde. Und genau dafuer kann man new gebrauchen.
Richtig sollte das ganze in etwa so aussehen:
Code:
class A
{
public:
A(int x) : m_x(x) {}
A * CreateInstance()
{
A * pA = new A(5);
return pA;
}
int GetX() const
{
return m_x;
}
private:
int m_x;
};
int main()
{
A a(1);
A * anew = a.CreateInstance();
int x = anew->GetX();
delete anew;
}
Du musst dir beim Gebrauch von Objekten also immer Gedanken darueber machen, ob sie nach Ablauf ihres Gueltigkeitsbereichs immer noch gebraucht werden oder nicht.
<edit>
Ich hatte tatsaechlich 3 kleine Fehler eingebaut, jetzt sollte es stimmen.
</edit>
Kl.*j=75 funktioniert nicht ! Was hast du da überhaupt vor ? Willst du an die Stelle etwas schreiben, wo der Pointer hinzeigt ?! Dann musst du erst einen int mit 75 initialisieren und dann dann den Wert zuweisen.
versuch mal sowas wie:
Kl.j = new int(75)
Du hast wahrscheinlich uebersehen, dass er Kl.j bereits mit &l initialisiert hat. Dein Code funktioniert natuerlich auch, macht aber etwas anderes als er (seinem Code nach zu urteilen) vor hatte.
mfg,
bytepool
[1] Im uebrigen ist das wieder ein schoenes Beispiel dass C++ recht inkonsequent und verwirrend sein kann.