2013-03-18 30 views
9

Chcę, aby abstrakcyjna klasa podstawowa była niekopiowalna i wymusić, aby klasy, które z niej pochodzą, były niekopiowalne. Poniższy kod używa kodu Uncopyable, zgodnie z definicją w noncopyable.hpp, ale nadal pozwala D, klasie pochodnej, zdefiniować konstruktor kopii.Zakaz definiowania konstruktora kopiowania w odziedziczonej klasie

class noncopyable 
{ 
    protected: 
     noncopyable() {} 
     ~noncopyable() {} 
    private: // emphasize the following members are private 
     noncopyable(const noncopyable&); 
     const noncopyable& operator=(const noncopyable&); 
}; 

class D : noncopyable 
{ 
    public: 
     D() { } 
     D(const D&) { } 
}; 

int main() 
{ 
    D a; 
    D b(a); 

    return 0; 
} 

Ten kod kompiluje i działa (http://ideone.com/g4gGLm), kiedy oczekiwano go wyrzucić błąd kompilacji o D's kopię konstruktora. Może źle zinterpretowałem, co ta nieopłacalna klasa ma robić. Jeśli tak, czy istnieje sposób na wymuszenie, aby klasy pochodne nie definiowały konstruktora kopii? (Odpowiedź może korzystać z C++ 11, ale najlepiej nie doładowania)

Odpowiedz

3

Musisz usunąć konstruktora kopii D. Teraz możesz pozwolić na kopiowanie konstrukcji D's przez nie próbowanie kopiować-skonstruować klasę podstawową. Następujące warianty nie zostaną skompilowane:

class E: noncopyable 
{ 
}; 
E e, e2(e); 

class F: noncopyable 
{ 
public: 
    F(const F &init): noncopyable(init) 
    {} 
}; 
+0

Teraz rozumiem, do czego nie można kopiować (dzięki przykładowi klasy E). Dzięki – steve9164

12

Powodem tego jest to, że D(const D&) wywołuje domyślnego konstruktora klasy bazowej, a nie konstruktora kopiowania. (Intuicyjne na początku, ale to ma sens, biorąc pod uwagę wszystkie konstruktorzy zachowywać się jak ten)

Ponieważ konstruktor kopia nie jest wywoływana, kopia obiektu bazowego nie jest tworzony, chyba że wyraźnie poprosić o jednym:

D(const D& d) : noncopyable(d) { } 

co w rzeczywistości spowoduje błąd. W związku z tym Twój problem nie występuje - nie ma kopiowania z dnia noncopyable.

Nie jestem świadomy żadnego prostego sposobu na wymuszenie kopiowania klasy pochodnej, a także nie zaleciłbym korzystania z takiego, jeśli był.

+0

Dlaczego nie zaleca się zabronienia kopiowania? – steve9164

+1

@ steve9164 nie mówił tego - nie polecałbym pisania nieczytelnego kodu tylko w celu wymuszania klas pochodnych, aby uniemożliwić kopiowanie. –

+0

Jeśli wynikowy kod był nieczytelny, to tak, zgadzam się, że prawdopodobnie nie warto. – steve9164