2013-04-17 7 views
7

С классами C++ вы можете иметь производный класс наследовать переменную из своего родительского класса. Как я могу определить производный класс, так что var2 не наследуется в derivclass?Как не наследовать переменную в классах 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

Сделать 'private'. Вы не можете избежать наследования, если член является 'public'. –

+4

, если вы определяете его как 'private' в' mainclass', тогда 'дериватор' не сможет его коснуться, но он все равно будет * существует * – Dave

+0

личное ключевое слово. –

ответ

7

канонический способ предотвратить член от наследуются в C++, чтобы объявить его private. Производные классы, которые пытаются получить к нему доступ, затем выдают ошибку компилятора. Это будет выглядеть так:

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 
    } 
} 

Это самый простой способ достичь того, о чем вы просите.

+2

Я думаю, что в вашем примере переменные 'var1' и' var2' отменены. 'var1' будет недоступен в вашем примере. –

+0

Ах, ладно, спасибо. Точка - это я хочу, чтобы переменная, не наследующая, была доступна снаружи 'mainclass'. Если я определяю геттер и сеттер как 'inline', это вызовет накладные расходы? – tomsmeding

+0

@tomsmeding: Таким образом, вы хотите, чтобы переменная была доступна извне 'mainclass' для всех * кроме *' dedclass'? Я не думаю, что это возможно; если член является общедоступным или имеет публичный getter, тогда каждый может получить к нему доступ, включая производные классы. Или это удовлетворит ваши потребности, если производный класс может получить доступ к переменной, но только через геттер? – Edward

4

Вы можете сделать это private. Но вы, вероятно, не должны.

Тот факт, что он не должен наследовать некоторые вещи из Базы, означает, что он, вероятно, не должен наследовать от базы непосредственно.

Вместо этого создайте другой базовый класс и сделайте два класса наследуемыми от этой базы.

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

Если вы проголосуете, пожалуйста, любезность, чтобы хотя бы упомянуть почему. – stardust

+0

Я дам вам ответ, так как ваш ответ в порядке. Не знаю, почему кто-то проголосовал за это. –

+1

Я не проголосовал за ваш ответ, но лучше всего сделать так, чтобы ваши члены данных были приватными и определяли геттеры и сеттеры по мере необходимости. См. «Эффективный C++» Скотта Мейерса. – Dima

2

Как все говорят, вы можете сделать его частным в базовом классе, а затем он недоступен в любых подклассах. Однако, как говорит @Dave, он все равно будет существовать внутри базового класса. Если вы даже не хотите, чтобы он существовал как переменная, скрытая от подклассов, тогда вам придется вытащить ее из базового класса. Предполагая, что переменная необходима для чего-то, вам нужно будет создать новый подкласс, содержащий эту переменную.

0

Производный класс наследует каждый член его оснований. Полная остановка. Вы не можете выборочно наследовать части базового класса.

Создание переменной private не препятствует наследованию. Переменная все еще существует, но при обычных обстоятельствах она недоступна. С различными играми дружбы вы можете сделать его доступным. Возможно, часть путаницы здесь вызвана Java, где частные члены не унаследованы. То есть,

struct Base { 
private: 
    int i; 
}; 

struct Derived : Base { 
}; 

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

Если i не наследуется, то ошибка будет то, что d не имеет ни одного члена с именем i.

EDIT: другой, возможно, более значимым, например,

void f(); 

class Base { 
    void f(); 
}; 

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

С правилами Явы, вызов f() будет хорошо, и будет вызывать глобальную f().

+0

@ KonradRudolph - Э, ничего. А как насчет вас? –

+0

Не уверен, как вы получаете идею о том, что Java может магически удалять элементы при наследовании. Конечно, в Java производный класс наследует * all * его базовые элементы. –

+0

@ KonradRudolph - Я не сказал, что он может магически удалить членов при наследовании. –

0

В ответ на все другие ответы (и, возможно, переключение на стохастически) вы можете переключить основной и производный класс, где новый основной класс будет иметь все значения элементов, которые вы хотите в исходном производном классе, ненужные те, в новом производном классе (он же исходного основного класса)

Наблюдайте:

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

Мне нравится «из коробки», но это не решение. Скорее, это способ избежать проблемы. Обратное отношение наследования не всегда возможно. – Julian

Смежные вопросы