2016-04-07 4 views
3

IPrevent abgeleitete Klasse von Gießen zu stützen

class Rect{ 
    // stuff 
}; 

und

class SpecialRect:public Rect{ 
private: 
    operator const Rect(){return *this;}   // No implicits casts to Rect 
public: 
    // stuff 
}; 

SpecialRect haben erbt alle Eigenschaften und Methoden von Rect außer, dass ich will nicht explizite Konvertierungen von SpecialRect auf das vermeiden, Basisklasse Rect.

Im Code

SpecialRect oneSpecial; 
Rect aRect=oneSpecial;   // I want this to not compile. (to remind-me to declare aRect as SpecialTect) 

Compiliert ohne Fehler. (Ich weiß, dass das Deklarieren der Basisklasse Rect als private es tun würde, aber ich möchte nicht alle Methoden neu implementieren.)

Gibt es eine Möglichkeit, dies zu erreichen?

+4

es ist im Grunde wie fragen "Wie verhindere ich, dass meine Katze ein Tier ist", warum möchten Sie das verhindern? scheint wie gebrochenes Design –

+2

Sie verletzen die alte 'ist eine' Regel: Ihr spezielles Rechteck ist kein Rechteck. –

+0

Sie können sich das [Liskow-Substitutionsprinzip] (https://en.wikipedia.org/wiki/Liskov_substitution_principle) ansehen. – TartanLlama

Antwort

5

Deklarieren Privatkopie Konstruktor von SpecialRect in Rect wird den Trick tun, aber mit einem Nachteil: Rect hängt von SpecialRect-Deklaration ab. [aus Jarod42s Kommentar]

Hinweis: Denken Sie daran, dass Sie den leeren Konstruktor implementieren müssen, da es keinen Standardkonstruktor geben wird.

class SpecialRect; 

class Rect { 
public: 
    Rect(){} 

private: 
    Rect(const SpecialRect&); 
    //Rect(const SpecialRect&) = delete; // c++11 
}; 

class SpecialRect : public Rect { 

}; 


int main() 
{ 
    SpecialRect sr; 
    //Rect r1 = sr; // error: 'Rect::Rect(const SpecialRect&)' is private 
    //Rect r2(sr); // error: 'Rect::Rect(const SpecialRect&)' is private 

    Rect r3; 
    Rect r4(r3); 
    Rect r5 = r3; 
    return 0; 
} 

Eine andere Lösung ist explizite Standard Copykonstruktor in Rect zu erklären. Dies hat den Vorteil, nicht von Unterklassen abhängig zu sein, sondern hat Nebenwirkungen.

class Rect { 
public: 
    Rect(){} 
    explicit Rect(const Rect&); 
}; 

class SpecialRect : public Rect { 

}; 

int main() 
{ 
    SpecialRect sr; 
    //Rect r1 = sr; // Prevents this 
    Rect r2(sr); // Leaves this 

    Rect r3; 
    Rect r4(r3); 
    //Rect r5 = r3; // Side Effect: Prevents this 

    return 0; 
} 
+1

Aber 'Rect r (sr)' funktioniert immer noch. 'Rect (const SpecialRect &) = delete;' ist eine Alternative. – Jarod42

+0

Sie haben Recht, ich bemerkte das und arbeitete an einer anderen Lösung –

+1

Mit C++ 11, '= löschen;' ist besser als alt C++ 03 'private' ohne Implementierung. – Jarod42