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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
#1

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

20.11.2010, 02:13. Просмотров 982. Ответов 6
Метки нет (Все метки)

Тёмного времени суток!
Столкнулся с проблемой, основной смысл которой заложен ниже
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++ наследование
C++ Наследование
C++ наследование
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 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
1339 / 562 / 37
Регистрация: 31.03.2009
Сообщений: 1,918
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
Эксперт С++
1605 / 997 / 118
Регистрация: 27.09.2009
Сообщений: 1,923
Завершенные тесты: 1
20.11.2010, 09:01     Наследование #4
Цитата Сообщение от NightmareZ Посмотреть сообщение
следовательно, от абстрактности этого класса никак не избавиться, ибо в дочерних классах она видна не будет
Это неверно. Сама функция видна не будет, но это и не требуется - ведь её всё равно переопределят. Более того, при переопределении можно и изменить её область видимости. Конечно, такой функцией всё равно нельзя будет пользоваться через указатель на базовый класс (ведь там она private), но в ряде случаев осмысленное использование закрытых чистых виртуальных функций вполне возможно и целесообразно.
NightmareZ
1339 / 562 / 37
Регистрация: 31.03.2009
Сообщений: 1,918
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++ Наследование
Наследование C++
C++ Наследование
Наследование C++

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

Или воспользуйтесь поиском по форуму:
Mr.X
Эксперт С++
3040 / 1685 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
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     Наследование
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru