2011-11-06 8 views

Odpowiedz

4

kiedy wykonać w kodzie poniżej:

A* ptr = new A(obj); 

będziesz zawsze uzyskać Instancja. obj zostanie potraktowane jako A, a nowy A zostanie utworzony w oparciu o "część" obj.

Lepsze podejście jest jak wskazano we wcześniejszej odpowiedzi, dodaj wirtualną metodę MakeCopy do klasy bazowej i zaimplementuj ją dla klas pochodnych.

virtual A* MakeCopy(); 

Ta metoda jest realizowana przez wykonanie kopii obiektu, dla którego została wywołana. Następnie zostaje zaimplementowana w klasach pochodnych, więc jeśli masz wskaźnik A, który jest w rzeczywistości obiektem B, otrzymasz prawdziwą kopię B i unikniesz "rozcięcia" występującego w twoim przykładzie.

5

Zwrócony obiekt ma typ pointer to A, co oznacza, że ​​obiekt wskazywany przez hPtr jest typu A. To nie jest bezpieczne, ponieważ metody wywoływania lub członkowie wyłącznie dla B spowodują awarię lub niezdefiniowane zachowanie. Prawdopodobnie szukasz numeru factory pattern.

1

To nie jest bezpieczne, jest niepoprawne, a kompilator powinien dać ci jakąś diagnostykę. Czy próbowałeś skompilować się z g++ -Wall, jeśli używasz GCC?

+0

Przepraszam, napisałem kod z pamięci i nie mogłem spróbować się skręcić. – jlledom

2

bezpiecznym sposobem jest dostarczenie sposobu wirtualny klon

#include <memory> 

class Base 
{ 
public: 
    virtual std::unique_ptr<Base> Clone() = 0; 
}; 

class Derived : public Base 
{ 
public: 
    Derived(int i) : i_(i) 
    { 

    } 

    std::unique_ptr<Base> Clone() 
    { 
     return std::unique_ptr<Derived>(new Derived(i_)); 
    } 

private: 
    int i_; 
}; 


std::unique_ptr<Base> copyToHeap(std::unique_ptr<Base> obj) 
{ 
    return obj->Clone(); 
} 
1

Nie skompilować:

B *hPtr=copyToHeap(bObj); //error: invalid conversion from ‘A*’ to ‘B*’ 

Jeśli zmienić typ hPtr do A* to kompiluje, ale nadal uzyskać Obiekt A. Domyślny konstruktor kopiowania dla A, którego używasz, utworzy obiekt A i skopiuje pola obiektu B, które zostały zdefiniowane w A, odcinając część.

0

Z powodu wszystkich problemów opisanych powyżej/w tym poście - jeśli w ogóle można tego uniknąć (i nie mogę wymyślić przyczyny, dla której nie mógłbyś) - nie powinieneś projektować swojego kodu, aby wymagał "copyToHeap".

Jak wskazuje Luchian, prawdopodobnie potrzebujesz fabryki. Fabryka na początku tworzy obiekt na stercie (i zwraca inteligentny wskaźnik do zarządzania czasem życia obiektu/wskaźnika/pamięci).

Powiązane problemy