2013-04-17 13 views
7

W klasach C++ klasa pochodna może dziedziczyć zmienną z klasy nadrzędnej. Jak zdefiniować pochodną klasy tak, aby var2 nie została odziedziczona w derivclass?Jak nie dziedziczyć zmiennej w klasach C++

class mainclass{ 
public: 
    int var1; 
    char var2; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
} 
class derivclass : mainclass{ 
public: 
    void test(){ 
     cout<<var1<<var2<<endl; 
     //want a compiler error here that var2 is not defined 
    } 
} 
+3

Make it 'private'. Nie można uniknąć dziedziczenia, jeśli członek jest "publiczny". –

+4

jeśli zdefiniujesz go jako 'prywatny' w' mainclass', to 'derivclass' nie będzie mógł go dotknąć, ale nadal będzie istnieć * – Dave

+0

prywatne słowo kluczowe zrobiłoby. –

Odpowiedz

7

Klasycznym sposobem zapobiegania członka z dziedziczone C++ jest to private zgłosić. Klasy pochodne, które próbują uzyskać do niego dostęp, będą wtedy zgłaszać błąd kompilatora. Wyglądałby tak:

class mainclass{ 
public: 
    int var1; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
private: 
    char var2; 
} 
class derivclass : mainclass { 
    public: 
    void test(){ 
     cout<<var1<<var2<<endl; 
     //compiler error here; var2 is not accessible 
    } 
} 

To najprostszy sposób na osiągnięcie tego, o co prosisz.

+2

Myślę, że masz 'var1' i' var2' odwrócone w twoim przykładzie. 'var1' byłby niedostępny w twoim przykładzie. –

+0

Ah OK, dzięki. Chodzi o to, że chcę udostępnić niedostępną zmienną z zewnątrz "mainclass". Jeśli zdefiniuję getter i setter jako 'inline', czy to spowoduje obciążenie? – tomsmeding

+0

@tomsmeding: Więc chcesz, aby zmienna była dostępna z zewnątrz 'mainclass' dla wszystkich * z wyjątkiem *' derivclass'? Nie sądzę, że to możliwe; jeśli członek jest publiczny lub ma publiczny odbiór, wówczas każdy może uzyskać do niego dostęp, w tym klasy pochodne. A może zaspokoiłoby to twoje potrzeby, gdyby klasa pochodna mogła uzyskać dostęp do zmiennej, ale tylko przez getter? – Edward

4

Możesz to zrobić private. Ale prawdopodobnie nie powinieneś.

Fakt, że nie powinien dziedziczyć niektórych rzeczy z bazy oznacza, że ​​prawdopodobnie nie powinien w ogóle dziedziczyć bezpośrednio od bazy.

Zamiast tego utwórz kolejną klasę bazową i uczyń dwie klasy dziedziczącymi z tej bazy.

class Baseclass{ 
public: 
    void test(){ 
     cout<<var1<<endl; 
    } 
protected: 
    int var1; 

} 

class mainclass : public Baseclass{ 
public: 
    char var2; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
} 

class derivclass : Baseclass{ 
public: 
    void test(){ 
     cout<<var1<<endl; 
    } 
} 
+0

Jeśli zagłosujesz w dół, uprzejmie prosimy o podanie przyczyny. – stardust

+0

Dam ci punkt zwrotny, ponieważ twoja odpowiedź jest w porządku. Nie wiem, dlaczego ktoś głosował na to. –

+1

Nie zagłosowałem na twoją odpowiedź, ale najlepszą rzeczą jest zawsze uczynić swoich członków danych prywatnymi, a także zdefiniować w razie potrzeby moduły pobierające i ustawiające. Zobacz "Efektywny C++" Scotta Meyersa. – Dima

2

Jak wszyscy inni mówią, możesz uczynić go prywatnym w klasie bazowej, a następnie nie jest dostępny w żadnej z podklas. Jednak, jak mówi @Dave, nadal będzie istnieć w klasie bazowej. Jeśli nawet nie chcesz, aby istniała jako zmienna ukryta przed podklasami, musisz ją usunąć z klasy bazowej. Zakładając, że zmienna jest potrzebna do czegoś, musisz utworzyć nową podklasę, która zawiera tę zmienną.

0

Klasa pochodna dziedziczy każdego członka swojej bazy. Kropka. Nie można selektywnie dziedziczyć części klasy bazowej.

Ustawienie zmiennej prywatnej nie zapobiega dziedziczeniu. Zmienna jest nadal dostępna, ale w zwykłych okolicznościach nie jest dostępna. Dzięki różnym przyjaźniom możesz ją udostępnić. Być może część zamieszania jest spowodowana przez Javę, gdzie prywatni członkowie nie są dziedziczeni. Oznacza to, że

struct Base { 
private: 
    int i; 
}; 

struct Derived : Base { 
}; 

Derived d; 
d.i = 3; // error: d.i is not accessible 

Jeśli i nie odziedziczył, błąd będzie, że d ma elementu o nazwie i.

EDIT: inny, być może bardziej wymowny, przykład

void f(); 

class Base { 
    void f(); 
}; 

class Derived : Base { 
    void g() { 
     f(); // error: Base::f is not accessible 
}; 

Z zasadami Javy, wezwanie do f() byłoby w porządku, i nazwałbym globalny f().

+0

@KonradRudolph - Uh, nic. Co z Tobą? –

+0

Nie jestem pewien, w jaki sposób uzyskujesz pomysł, że Java może magicznie usuwać członków podczas dziedziczenia. Oczywiście w Javie klasa pochodna dziedziczy * wszystkie * członków jej bazy. –

+0

@KonradRudolph - Nie powiedziałem, że magicznie może usunąć członków po odziedziczeniu. –

0

W odpowiedzi na wszystkie inne odpowiedzi (i ewentualnie na niedopuszczenie do Stochastycznego), możesz zmienić klasę główną i pochodną, ​​gdzie nowa główna klasa będzie miała wszystkie wartości składowe, które chcesz w oryginalnej klasie pochodnej, umieszczając niepotrzebne ci w nowej klasie pochodnej (aka oryginalnego głównej klasy)

przestrzegać:

class newMainClass{ 
public: 
    int var1; 
    virtual void test(){ //added virtual here so there aren't two definitions for test() 
     cout<<var1<<var2<<endl; 
     //want a compiler error here that var2 is not defined 
    } 
} 

class newDerivedClass : public newMainClass{ 
public: 
    char var2; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
} 
+0

Lubię myśleć "po wyjęciu z pudełka", ale to nie jest rozwiązanie. Jest to raczej sposób na uniknięcie problemu. Odwracanie relacji dziedziczenia nie zawsze jest możliwe. – Julian

Powiązane problemy