2016-08-30 15 views
2

Also sagen wir, ich habe eine Klasse MyClass. Jetzt möchte ich eine andere Klasse namens Animals verwenden, würde ich wahrscheinlich folgendes tun.Initialisierung durch Zeiger in C++

class MyClass 
{ 
public: 
    MyClass(); 
private: 
    Animals animals; 
}; 

Allerdings kann ich auch dies tun:

class MyClass 
{ 
public: 
    MyClass(); 
private: 
    Animals* animals; 
}; 

und dann die Klasse im Konstruktor initialisieren mit:

animals = new Animals(); 

Was ist der Unterschied zwischen den beiden unterschiedlichen Ansätze ist, das ist, besser und warum? Bei meiner Verwendung sollte Animals nur innerhalb von MyClass verwendet werden. Meine Frage ist hauptsächlich über Leistung und Speicher, ich meine, ist die Initialisierung von Zeiger erfordert mehr Ressourcen oder nicht?

+4

Das klingt wie eine Hausaufgabe. Können Sie Ihre Frage ein wenig nach unten geben – TankorSmash

+2

Sieht so aus, als müssten Sie [this] lesen (http://stackoverflow.com/questions/162941/why-use-pointers) – NathanOliver

+0

@TankorSmash es ist keine Hausaufgabenfrage, aber ich werde versuchen Sie, meine Frage zu verbessern – daljit97

Antwort

5

Wenn Sie überlegen, wie Speicher in einer Klasse verwaltet wird, sollte es klar werden. Wenn Sie in Ihrer Klasse Animals animal deklarieren, ist der Speicherplatz für animal im Speicherbedarf Ihrer Klasse reserviert. Aber wenn Sie Animals* animal deklarieren, ist nur ein Zeiger auf Animal im Speicherabdruck Ihrer Klasse reserviert.

Keines ist besser, da es von Ihren Umständen abhängt. Wenn Sie immer ein Tier erstellen und MyClass es besitzt, verwenden Sie den ersten Ansatz, da es nur eine Speicherzuweisung erfordert. Wenn animals oft leer sein kann und Speicher ein Problem ist, dann sollten Sie den zweiten Ansatz verwenden.

Übrigens, wenn Sie C++ 11 oder höher verwenden, möchten Sie vielleicht std::unique_ptr<Animal> für den zweiten Fall betrachten.

1

Wenn die alleinige Existenz des animals Objekt auf dem Objekt MyClass abhängen, verwenden Sie dann Eindämmung:

class MyClass 
{ 
public: 
    MyClass(); 
private: 
    Animals animals; 
}; 

Wenn die Existenz von animals unabhängig ist, aber MyClass wollen einen Verein, um es zu halten, dann verwenden Zeiger:

class MyClass 
{ 
public: 
    MyClass(); 
private: 
    Animals * animals; 
}; 

die Wahl selbst auf dem Objekt abhängt Erstes Modell.

Es gibt viele Überlegungen beteiligt.

Im Containment-Ansatz wird der Speicher für animals zusammen mit dem Objekt MyClass zugewiesen. Sie gehen immer zusammen und MyClass voll besitztanimals.

In der Zeiger-Ansatz sind sie zwei separate Teile des Speichers und müssen separat zugewiesen werden. Es ist ein Verein ohne Eigentum. Während der gesamten Lebensdauer MyClass können mehrere Dinge passieren:

  • myclass assoziieren zu keiner Animals, das heißtanimals = nullptr
  • myclass können verschiedene Animals zu verschiedener Zeit assoziieren, d.h. animals = a1; /* ... */; animals = a2;

Außerdem mehr Objekte, entweder MyClass Objekte oder andere Arten von Objekten , may hold the same animals` Zeigern.

Wenn das Objekt animals zerstört wird, haben diese Objekte das Risiko, den veralteten Zeiger zu verwenden. Daher ist ein Mechanismus erforderlich, um dies zu vermeiden.

Mit Zeiger-Ansatz, kann man Laufzeit-Polymorphie verwenden, die in der Containment-Ansatz nicht möglich ist. Zum Beispiel

void MyClass::setAnimal(Animal * a) { 
    animal = a; 
} 

Animal * a1 = new Lion; 
Animal * a2 = new Tiger; 

MyClass x1; 
x1.setAnimal(a1); 

MyClass x2; 
x2.setAnimal(a2); 
0

Aus gestalterischen Sicht ist MyClass ein Behälter mit einem Animal. Im ersten Beispiel haben Sie immer eine Animal. Im zweiten Beispiel können Sie eine Animal haben oder nicht. Wenn Sie zum Beispiel einen Käfig mit einem Vogel haben, hat Ihr erster Käfig immer einen Vogel und er darf nicht leer sein, aber das zweite Beispiel kann ein Vogel sein oder auch nicht.

Dies wird Cardinality (0, 1) in Datenbanken genannt. Sie können sich vorstellen, dass Sie eine Sammlung von Animals mit einem oder null Elementen haben (auch wenn Sie kein Array haben).

Der zweite Aspekt ist, dass Sie im ersten Beispiel immer die gleichen Animal haben, und Sie können nicht frei herumgehen und die Lebensdauer der Animal hängt ausschließlich vom Container ab. Das zweite Beispiel ermöglicht es, die Animal in einen neuen Container zu verschieben oder denselben in zwei verschiedenen Containern zu haben und die Lebensdauer des Containers zu entkoppeln.

Dann, mit C++, müssen Sie Speicherzuweisung und Besitz berücksichtigen, wo wir in der Regel intelligente Zeiger verwenden, um die Freigabe des Tieres vorzunehmen.

Verwandte Themen