Ansprechen einerPointervarible von einer Klassen

R

rdg

???
Hi,

ich habe mal wieder ein paar Verständnissproblem bei c++, wo ich hoffe das Ihr mir dabei helfen könnt.
Zum einen habe ich eine Klasse
Klasse{
int i;
int *j;
Klasse(int _i, int *_j);
}

Wenn ich nun die Klasse initialisiere, wie kann ich dann den Pointer ansprechen?
int l=34;
Klasse Kl(5,&l);
Kl.i=53; funkioniert tadellos
Kl.*j=75; funktioniert nicht warum?

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

Ich hoffe Ihr könnt mir dabei helfen, ich hänge daran schon seit längerem fest.

vielen dank für Eure Bemühungen!!!
Gruß rdg
 
So, wie ich Pointer verstanden habe kann man in Pointern keine Werte speichern, da sie ja nur ein Zeiger auf eine Speicherzelle sind. D.h einem Pointer einen Wert zuweisen macht keinen Sinn.
Was sehrwohl Sinn machen kann ist einen Pointer auf ein Objekt (bei dir wäre das Klasse *pK; )

Aber ich weiss nicht, ob es richtig ist, was ich geschrieben habe.

Grüße, Blender3D
 
Naja, eigentlich kann man in Zeiger auch Werte Speichern, nur Das man bei Ihnen zusätzlich noch Die Adresse einer anderen Variable Speichern kann und so auf diese Zugreifen. Bei normalen nicht Klassen basierten Pointern habe ich damit auch keine Probleme nur bei einer Klasse funktioniert es nicht, was ich einfach nicht versehe.
:think::think:
 
Zuletzt bearbeitet:
Wenn ich nun die Klasse initialisiere, wie kann ich dann den Pointer ansprechen?
int l=34;
Klasse Kl(5,&l);
Kl.i=53; funkioniert tadellos
Kl.*j=75; funktioniert nicht warum?


Klasse K = new Klasse(5,&l); und
Klasse *pK = new Klasse(5,&l);

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)
(i.A. macht das aber keinen Sinn in einer Klasse einen Zeiger auf einen int zu definieren...)


Zu deiner zweiten Frage. Nur
Klasse *pK = new Klasse(5,&l); wird funktionieren, denn mit dem "new"- Operator wird ein Zeiger auf eine Klasse zurückgegeben.

Grüße,
h2o
 
Naja, eigentlich kann man in Zeiger auch Werte Speichern, nur Das man bei Ihnen zusätzlich noch Die Adresse einer anderen Variable Speichern kann und so auf diese Zugreifen.

Streich das am besten ganz schnell aus deinem Gehirn :D
Zeiger speichern NUR Adressen des Speichers. Mithilfe der Zeiger kanst du auf die Werte zugreifen, die an dieser Adresse gespeichert sind. Wen du z.B.
so was machst:
Code:
int *ptr = &variable;
cout << *ptr;
wird der Wert von variable ausgegeben.
Wen du das machst:
Code:
int *iptr = &variable;
cout << ptr;
dan wird die Speicher Adresse ausgegeben.

Tuxus
 
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:
Code:
*(Kl.j) = 75;
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.
 
Zuletzt bearbeitet:
cool, vielen dank bytepool !

deine Erklärung, vor allem *(Kl.j) hat mir sehr geholfen. Natürlich sollte man keine Pointer bzw. so hart verwenden, wollte es halt mal ausprobieren.

Streich das am besten ganz schnell aus deinem Gehirn
Zeiger speichern NUR Adressen des Speichers. Mithilfe der Zeiger kanst du auf die Werte zugreifen, die an dieser Adresse gespeichert sind. Wen du z.B.
P.S.: Klar Pointer nur seine Adresse(&), die der anderen Variablen( ) und "deren Wert" (natürlich nicht wirklich) (*)


vielen vielen dank für Eure hilfe! :)
 

Ähnliche Themen

Segmentation fault -- warum?

qt Anfängerprobleme

Tomcat6 startet nicht

Kein Hardwaremixing: Workarount gesuchd

Cardreader automount?

Zurück
Oben