it-swarm.com.de

C++ - Zeiger auf Objekte

Haben Sie in C++ immer einen Zeiger auf ein Objekt mit dem Schlüsselwort new initialisiert?

Oder kannst du auch das haben:

MyClass *myclass;

myclass->DoSomething();

Ich dachte, dies wäre ein Zeiger, der auf dem Stapel statt auf dem Haufen zugewiesen wurde, aber da Objekte normalerweise Haufen zugewiesen werden, denke ich, dass meine Theorie wahrscheinlich fehlerhaft ist.

Bitte beraten.

21
Tony The Lion

Nein, Sie können Zeiger haben, um zugeordnete Objekte zu stapeln:

MyClass *myclass;
MyClass c;
myclass = & c;
myclass->DoSomething();

Dies ist natürlich üblich, wenn Zeiger als Funktionsparameter verwendet werden:

void f( MyClass * p ) {
    p->DoSomething();
}

int main() {
    MyClass c;
    f( & c );
}

Auf die eine oder andere Weise muss der Zeiger jedoch immer initialisiert werden. Dein Code:

MyClass *myclass;
myclass->DoSomething();

führt zu diesem gefürchteten Zustand, undefiniertem Verhalten .

33
anon

Nein, Sie können das nicht tun, MyClass *myclass definiert einen Zeiger (Speicher für den Zeiger wird im Stapel reserviert), der auf eine zufällige Speicherstelle zeigt. Der Versuch, diesen Zeiger zu verwenden, führt zu undefiniertem Verhalten.

In C++ können Sie Objekte entweder auf Stapel oder Heap wie folgt erstellen:

MyClass myClass;
myClass.DoSomething();

Oben wird myClass auf Stack aufgeteilt (der Begriff ist nicht in dem Standard enthalten, den ich denke, aber ich benutze ihn der Klarheit halber). Der für das Objekt zugewiesene Speicher wird automatisch freigegeben, wenn die Variable myClass den Gültigkeitsbereich verlässt.

Eine andere Möglichkeit, Speicher zuzuordnen, ist die Ausführung einer new. In diesem Fall müssen Sie dafür sorgen, dass der Speicher freigegeben wird, indem Sie delete selbst ausführen.

MyClass* p = new MyClass();
p->DoSomething();
delete p;

Denken Sie an den delete-Teil, andernfalls tritt ein Speicherverlust auf. 

Ich ziehe es vor, die vom Stapel zugewiesenen Objekte immer zu verwenden, da ich mich nicht um die Speicherverwaltung kümmern muss.

22
Naveen

wenn Sie das Objekt auf dem Stapel haben möchten, versuchen Sie Folgendes:

MyClass myclass;
myclass.DoSomething();

Wenn Sie einen Zeiger auf dieses Objekt benötigen:

MyClass* myclassptr = &myclass;
myclassptr->DoSomething();
10
Johan Kotlinski

Zuerst muss ich sagen, dass Ihr Code, 

MyClass *myclass;
myclass->DoSomething();

führt zu einem undefinierten Verhalten ..__, da der Zeiger "myclass" nicht auf Objekte vom Typ "MyClass" zeigt.

Hier habe ich drei Vorschläge für Sie: - 

option 1: - Sie können einfach ein Objekt vom Typ MyClass auf dem Stapel deklarieren und verwenden, wie unten beschrieben.

MyClass myclass; //allocates memory for the object "myclass", on the stack.
myclass.DoSomething();

option 2: - Mit dem neuen Operator.

MyClass *myclass = new MyClass();

Drei Dinge werden hier geschehen.

i) Ordnet Speicher für das Objekt "MyClass" auf dem Heap zu.

ii) Speicher für den Zeiger "myClass" vom Typ "myclass" auf dem Stack. 

iii) Der Zeiger "myclass" zeigt auf die Speicheradresse des Objekts "MyClass" auf dem Heap

Jetzt können Sie den Zeiger verwenden, um auf Elementfunktionen des Objekts zuzugreifen, nachdem der Zeiger durch "->" dereferenziert wurde.

myclass->DoSomething();

Sie sollten jedoch den dem Objekt "MyClass" zugewiesenen Speicher auf dem Heapspeicher freigeben, bevor Sie aus dem Bereich zurückkehren, es sei denn, Sie möchten, dass das Objekt vorhanden ist. Andernfalls führt dies zu einem Speicherleck !

delete myclass; // free the memory pointed by the pointer "myclass"

Option 3: - können Sie auch wie folgt tun.

MyClass myclass; // allocates memory for the "MyClass" type object on the stack.
MyClass *myclassPtr; // allocates memory for the "MyClass" type pointer on the stack.
myclassPtr = &myclass; // "myclassPtr" pointer points to the momory address of myclass object.

Zeiger und Objekt befinden sich jetzt auf dem Stapel ..__ Jetzt können Sie diesen Zeiger nicht außerhalb des aktuellen Bereichs zurückgeben, da sowohl der zugewiesene Speicher des Zeigers als auch das Objekt beim Verlassen des Bereichs freigegeben werden.

Zusammenfassend ordnen die Optionen 1 und 3 ein Objekt auf dem Stapel zu, während dies nur die Option 2 auf dem Heap erledigt.

2
Malith

wenn Sie auf eine Methode zugreifen möchten:

1) bei Verwendung eines Objekts einer Klasse:

Myclass myclass;
myclass.DoSomething();

2) bei Verwendung eines Zeigers auf ein Objekt einer Klasse:

Myclass *myclass=&abc;
myclass->DoSomething();
1
harsha217

Wenn Sie in Ihrer Klasse eine Methode als statisch definiert haben, ist dies tatsächlich möglich.

    class myClass
    {
    public:
        static void saySomething()
        {
            std::cout << "This is a static method!" << std::endl;
        }
    }; 

Und von main aus deklarieren Sie einen Zeiger und versuchen, die statische Methode aufzurufen.

    myClass * pmyClass;
    pmyClass->saySomething();

/*    
Output:
This is a static method!
*/

Dies funktioniert gut, da statische Methoden nicht zu einer bestimmten Instanz der Klasse gehören und nicht als Teil einer Instanz der Klasse zugeordnet werden. 

Weitere Informationen zu statischen Methoden finden Sie hier: http://en.wikipedia.org/wiki/Static_method#Static_methods

1
Parth Kothari

Einfache Lösung für Cast-Zeiger auf Objekt

Online-Demo

class myClass
{
  public:
  void sayHello () {
    cout << "Hello";
  }
};

int main ()
{
  myClass* myPointer;
  myClass myObject = myClass(* myPointer); // Cast pointer to object
  myObject.sayHello();

  return 0;
}
0
Ali Soltani