Форум программистов, компьютерный форум CyberForum.ru

Наследование - C++

Восстановить пароль Регистрация
 
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
20.11.2010, 02:13     Наследование #1
Тёмного времени суток!
Столкнулся с проблемой, основной смысл которой заложен ниже
C++
1
2
3
4
5
6
7
8
9
10
class Parent 
{
void F() = 0;
}
class Child: protected Parent
{
void F() {}
}
 
Parent *ptr = new Child;
В результате ошибка
error C2243: 'type cast' : conversion from 'class ... *' to 'class ...*' exists, but is inaccessible
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.11.2010, 02:13     Наследование
Посмотрите здесь:

C++ Наследование
Наследование C++
C++ наследование
C++ Наследование?!
C++ наследование
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
20.11.2010, 03:36     Наследование #2
alexsvk,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Parent 
{
public:
    virtual void F() = 0;
};
 
class Child: public Parent
{
public:
void F() {}
};
 
int main()
{
    Parent *ptr = new Child;
}
NightmareZ
 Аватар для NightmareZ
1336 / 559 / 37
Регистрация: 31.03.2009
Сообщений: 1,907
20.11.2010, 04:01     Наследование #3
Цитата Сообщение от alexsvk Посмотреть сообщение
Тёмного времени суток!
Столкнулся с проблемой, основной смысл которой заложен ниже
C++
1
2
3
4
5
6
7
8
9
10
class Parent 
{
void F() = 0;
}
class Child: protected Parent
{
void F() {}
}
 
Parent *ptr = new Child;
В результате ошибка
error C2243: 'type cast' : conversion from 'class ... *' to 'class ...*' exists, but is inaccessible
Во-первых, спецификатор чистой функции есть ( = 0 ), но функция эта не виртуальная. Что, естессно, некорректно. Нужно перед функцией F в классе Parent дописать virtual.

Во-вторых, если явно не указан модификатор доступа ( private, protected или public ) для членов класса, по умолчанию подразумевается private, а потому функция F, объявленная в классе Parent, будет только в нём и видна. А, следовательно, от абстрактности этого класса никак не избавиться, ибо в дочерних классах она видна не будет. И функция F в дочернем классе не перегружает функцию F из класса Parent.

В-третьих при защищённом (protected) наследовании нельзя неявно преобразовывать указатель на объект класса-наследника в указатель на базовый класс.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
20.11.2010, 09:01     Наследование #4
Цитата Сообщение от NightmareZ Посмотреть сообщение
следовательно, от абстрактности этого класса никак не избавиться, ибо в дочерних классах она видна не будет
Это неверно. Сама функция видна не будет, но это и не требуется - ведь её всё равно переопределят. Более того, при переопределении можно и изменить её область видимости. Конечно, такой функцией всё равно нельзя будет пользоваться через указатель на базовый класс (ведь там она private), но в ряде случаев осмысленное использование закрытых чистых виртуальных функций вполне возможно и целесообразно.
NightmareZ
 Аватар для NightmareZ
1336 / 559 / 37
Регистрация: 31.03.2009
Сообщений: 1,907
20.11.2010, 11:27     Наследование #5
Цитата Сообщение от Nick Alte Посмотреть сообщение
Это неверно. Сама функция видна не будет, но это и не требуется - ведь её всё равно переопределят. Более того, при переопределении можно и изменить её область видимости. Конечно, такой функцией всё равно нельзя будет пользоваться через указатель на базовый класс (ведь там она private), но в ряде случаев осмысленное использование закрытых чистых виртуальных функций вполне возможно и целесообразно.
Блин, перегрузить и переопределить - две большие разницы.
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
20.11.2010, 12:51  [ТС]     Наследование #6
Цитата Сообщение от NightmareZ Посмотреть сообщение
Во-первых, спецификатор чистой функции есть ( = 0 ), но функция эта не виртуальная. Что, естессно, некорректно. Нужно перед функцией F в классе Parent дописать virtual.

Во-вторых, если явно не указан модификатор доступа ( private, protected или public ) для членов класса, по умолчанию подразумевается private, а потому функция F, объявленная в классе Parent, будет только в нём и видна. А, следовательно, от абстрактности этого класса никак не избавиться, ибо в дочерних классах она видна не будет. И функция F в дочернем классе не перегружает функцию F из класса Parent.

В-третьих при защищённом (protected) наследовании нельзя неявно преобразовывать указатель на объект класса-наследника в указатель на базовый класс.
Теперь вопрос: почему при защищённом наследовании нельзя писать
C++
1
Parent *g = new Child
?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.11.2010, 14:30     Наследование
Еще ссылки по теме:

Наследование наследование ) C++
C++ Наследование

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Mr.X
Эксперт С++
 Аватар для Mr.X
2801 / 1577 / 247
Регистрация: 03.05.2010
Сообщений: 3,662
20.11.2010, 14:30     Наследование #7
Цитата Сообщение от alexsvk Посмотреть сообщение
Теперь вопрос: почему при защищённом наследовании нельзя писать
C++
1
Parent *g = new Child
?
Защищенное наследование делает все интерфейсные public-функции базового класса protected-функциями, т.е. недоступными пользователю.
Если при защищенном наследовании разрешить присванивание
C++
1
Parent *g = new Child;
то произойдет нарушение инкапсуляции, так как пользователь получит доступ к protected-функциям потомка, унаследованным от базового класса.
Yandex
Объявления
20.11.2010, 14:30     Наследование
Ответ Создать тему
Опции темы

Текущее время: 05:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru