Na podstawie doświadczenia nie należy używać prostych wskaźników, ponieważ można łatwo zapomnieć o dodaniu odpowiednich mechanizmów niszczenia.
Jeśli chcesz uniknąć kopiowania, można przejść do realizacji Waga klasy z konstruktorem kopiującym i skopiuj operator wyłączył:
class Weight {
protected:
std::string name;
std::string desc;
public:
Weight (std::string n, std::string d)
: name(n), desc(d) {
std::cout << "W c-tor\n";
}
~Weight (void) {
std::cout << "W d-tor\n";
}
// disable them to prevent copying
// and generate error when compiling
Weight(const Weight&);
void operator=(const Weight&);
};
Następnie dla klasy wykonawczego pojemnik, należy shared_ptr
lub unique_ptr
do wdrożenie elementu danych:
template <typename T>
class QList {
protected:
std::vector<std::shared_ptr<T>> v;
public:
QList (void) {
std::cout << "Q c-tor\n";
}
~QList (void) {
std::cout << "Q d-tor\n";
}
// disable them to prevent copying
QList(const QList&);
void operator=(const QList&);
void append(T& t) {
v.push_back(std::shared_ptr<T>(&t));
}
};
Twoja funkcja dodawania elementu byłoby skorzystać lub Return Value Optimization i nie wywołać konstruktor kopiujący (co nie jest określony):
QList<Weight> create (void) {
QList<Weight> ret;
Weight& weight = *(new Weight("cname", "Weight"));
ret.append(weight);
return ret;
}
Po dodaniu elementu, niech pojemnik wziąć własność obiektu, więc nie zwalnianie go:
QList<Weight> ql = create();
ql.append(*(new Weight("aname", "Height")));
// this generates segmentation fault because
// the object would be deallocated twice
Weight w("aname", "Height");
ql.append(w);
Albo lepiej, zmusić użytkownika do przekazania implementacji qlist tylko inteligentne wskaźniki:
void append(std::shared_ptr<T> t) {
v.push_back(t);
}
A poza klasa qlist będziesz go używać jak:
Weight * pw = new Weight("aname", "Height");
ql.append(std::shared_ptr<Weight>(pw));
Korzystanie shared_ptr również mogłaby „wziąć” obiektów z kolekcji, należy wykonać kopie, usunięcia ze zbioru, ale używać lokalnie - za kulisami to być tylko same tylko przedmiot.
Oba warianty wyglądają okropnie źle (chociaż tylko pierwszy jest w rzeczywistości uszkodzony). –
Jeśli są to 'QList' z biblioteki' Qt', to mają specjalne właściwości liczenia akcji, które nie są typowe dla biblioteki standardowej lub innych typów regularnych. – woolstar