2013-03-19 3 views
1

У меня есть этот код, обратите внимание, что две линии были закомментированачлен переменной наследования

#include <iostream> 

class foo { 
public: 
    foo(); 
    int i; 
}; 

class bar: foo { 
public: 
    bar(); 
    //int i; 
}; 

foo::foo() 
{ 
    i = 2; 
} 

bar::bar() 
{ 
    i = 4; 
} 

int main() 
{ 
    bar *b = new(bar); 
    //std::cout << "bi = " << b->i << std::endl; /*line 28*/ 
    foo *f = (foo*) b; 
    std::cout << "fi = " << f->i << std::endl; 
} 

С двумя линиями закомментированными, код компилируется и выход

fi = 4 

С двумя линии без комментирования, код компилируется, а выход

bi = 4 

fi = 2 

Только с объявлением i wit хин класс бар закомментирован компиляция завершится неудачно

var.cc: In function ‘int main()’: 

var.cc:6:7: error: ‘int foo::i’ is inaccessible 

var.cc:28:30: error: within this context 

Я понимаю, первые два случая, но я не понимаю эту ошибку компиляции. Почему

переменная «i» доступна из конструктора бара, но не из указателя бара?

+0

Попробуйте унаследовать от Foo публично 'класса бар: общественный Foo' – StoryTeller

ответ

3

В частном наследовании все члены базового класса становятся private членами производного класса. Обратите внимание, что для классов по умолчанию наследование равно private, если вы не указали какой-либо.

С i действует как private члена bar, она может быть доступна в bar::bar(), но не из-за пределов функций-членов.

Хорошо читать:

What are access specifiers? Should I inherit with private, protected or public?

+0

Ah , и наследование является приватным по умолчанию. Создание публичного наследования позволяет компилировать, а выход - bi = 4 fi = 4. спасибо. –

+0

@ RichardJohnson: Посмотрите на ссылку, которую я предоставляю в ответ. Это должно объяснить вам все. –

+0

Спасибо за предоставление этой ссылки, это было очень информативно.Мне, возможно, придется прочитать его снова (и, возможно, снова), чтобы получить все подробности. –

1

Причина этого заключается в том, что вы используете личное наследство.

Для всех class es, private является модификатором доступа по умолчанию. Это означает, что члены и базы составляют private, если не указано иное.

Для struct по умолчанию public. Действительно, это единственная разница между class и struct.

Следовательно, при написании class bar: foo это эквивалентно class bar: private foo.

Чтобы избавиться от этой проблемы, вам необходимо сделать либо class bar: public foo, либо struct bar: foo, оба из которых эквивалентны в вашем примере (поскольку у вас нет членов, использующих модификатор доступа по умолчанию).

0

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

struct s1 
{ 
    int i; 
}; 

struct s2 : public s1 
{ 
    int i; 
}; 

int main() 
{ 
    s2 v; 

    v.s1::i = 1; 
    v.s2::i = 2; 

    std::cout << v.s1::i << v.s2::i << std::endl; 

    return 0; 
} 

Выход будет 12

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