Ich war auf der Suche, wie Pimpl in C++ zu verwenden, und ich fand dieses Stück Code in einem Tutorial:Warum verwenden wir "neu" in pimpl?
// In MyClass.h
class MyClassImp; // forward declaration of Pimpl
class MyClass
{
public:
MyClass();
~MyClass();
MyClass(const MyClass &rhs); // undefined for simplicity
MyClass& operator=(MyClass);
void Public_Method();
private:
MyClassImp *pimpl_; // the Pimpl
};
// In MyClass.cpp
#include "MyClass.h"
class MyClassImp
{
public:
void Private_Method() {} // dummy private function
int private_var_; // a private variable
};
MyClass::MyClass() : pimpl_(new MyClassImp())
{
}
MyClass::~MyClass()
{
delete pimpl_;
}
void MyClass::Public_Method()
{
pimpl_->Private_Method(); // do some private work
pimpl_->private_var_ = 3;
}
Aber ich konnte meinen Kopf nicht mit dem Grunde der Verteilung der MyClassImp in dem Haufen herumkommen Können wir nicht einfach eine Variable auf dem Stack verwenden?
Zur Klarstellung:
Wenn wir MyClassImp in einer getrennten .h und CPP-Datei setzen, und enthalten die .h in MyClass.h und MyClassImp pimpl_ verwenden; (ohne den Zeiger), würde es nicht den gleichen Effekt erzielen? Wenn die Implementierung von MyClassImp geändert wird, muss der Aufrufer (MyClass) nicht geändert und neu kompiliert werden. (Sie müssen immer noch neu verknüpfen)
* Welcher * Stapel? Der von 'MyClass :: MyClass'? Das wird zerstört, sobald der Konstruktor fertig ist. Der des Anrufers? * Sie kennen den Anrufer nicht. * – DevSolar
Fragen Sie, warum Sie 'MyClassImp * pimpl_ haben müssen; 'anstelle von' MyClassImp pimpl_; '? – NathanOliver
Um "auf dem Stapel" zu adressieren - innerhalb des Stapelrahmens von welchem Funktionsaufruf möchten Sie es haben? Und um zu erfahren, warum die automatische Speicherdauer nicht verwendet wird - der Hauptpunkt der Übung ist es, die Definition von "MyClassImp" zu verbergen. Wenn es ein direktes Mitglied wäre, müsste seine Größe (und damit seine Definition) bekannt sein. – Angew