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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.77
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
#1

Наследование абстрактного класса, компилятор достал материться - C++

24.08.2012, 16:31. Просмотров 1720. Ответов 21
Метки нет (Все метки)

Уже весь мозг сломал, не понимаю, почему компилятор начинает ругаться.
Есть абстрактный базовый класс в отдельном хедере:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once
 
class Shape
{
public:
    /*virtual double Dist(const Shape&) = 0; //1. */
    virtual void Read() = 0;
    virtual void Move(int delta_x, int delta_y) = 0;
    virtual Shape& Draw() = 0;
    virtual ~Shape() {};
private:
    virtual bool Set(int,int) = 0;
};//Shape
Есть его наследник в отдельном хедере:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#include "Shape.h"
 
class Point : public Shape
{
public:
    /*double Dist(const Point&); //2. */
    void Read();
    void Move(int delta_x, int delta_y);
    Point& Draw();
    ~Point();
    Point(int = 0, int = 0);
    Point(const Point&);
    Point& operator= (const Point&);
private:
    bool Set(int x_, int y_);
    int x, y;
};//Point
Описание класса Point отдельным файлом .cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include "math.h"
#include "Point.h"
 
using namespace std;
 
/*double Point::Dist(const Point& pt)
{
return 0;
}//Dist 3. */
 
void    Point::Read()
{
}//Read
 
void    Point::Move(int delta_x, int delta_y)
{
}//Move
 
bool    Point::Set(int x_, int y_)
{ 
}
 
Point&  Point::Draw()
{
return *this;
}//Draw
 
//Special methods
Point::~Point()
{
}//~Point
 
Point::Point(int x_, int y_)
{
}//Point
 
Point::Point(const Point& pt)
{
}//Point copy
 
//Redefined operators
Point& Point::operator= (const Point& rs)
{
return *this;
}//operator=
Я специально оставил функции пустыми, чтобы не отвлекал лишний текст. Вот в таком виде всё компилируется, ошибок НОЛЬ. Запросто создаются точки Point a,b, выполняются функции с ними.
Теперь убираем комментарии с номером 1, 2, 3 которые тут красным цветом выделены - иначе говоря добавляем в класс Shape вирт.функцию Dist, переопределяем её в классе Point, и при попытке создать точку Point a получаем ошибку:
C++
1
2
3
error C2259: 'Point' : cannot instantiate abstract class
1>          due to following members:
1>          'double Shape::Dist(const Shape &)' : is abstract
В припадке нубского недоумения ломаю клавиатуру и ругаюсь вслух, десять раз перепроверил, синтаксис вроде нигде не нарушен, создана вирт. функция в Shape, такая же функция записана в Point, переопределена, больше ничего не делал! Однако теперь мой класс Point принимается за абстрактный. А вместо объектов Point пытается создать объект Shape.

Укажите на ошибки пожалуйста, можете потроллить, если это очевидно, только объясните.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.08.2012, 16:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Наследование абстрактного класса, компилятор достал материться (C++):

Наследование абстрактного класса - C++
Не могли бы вы мне объяснить данный код: Actions *NewAct = new Array(); // строка 1 ((Array *)NewAct)-&gt;Set_arr(count); // строка 2 ...

Как обратится к обьекту класса, являющегося наследником абстрактного класса - C++
Здравствуйте! У меня есть 4 класса: один виртуальный, следующие 2 - наследуют виртуальный класс и последний класс содержит указатель на...

Поместить в динамически расширяемый массив объекты класса, производные от базового абстрактного класса - C++
Помогите пожалуйста новичку! (мне). Я хочу создать динамически расширяющийся массив указателей на базовый абстрактный класс,...

Использование абстрактного класса - C++
Доброго времени. Использую абстрактный класс Algorithm с абстрактным методом Calculate() и 5 производных от него классов, реализующих тот...

Деструктор абстрактного класса - C++
Почему деструктор абстрактного класса нужно делать виртуальным?

Объекты абстрактного класса - C++
Разбираю пример. В программе задается сразу 6 объектов. А нужно, чтобы количество объектов вводилось пользователем с клавиатуры. ...

21
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
24.08.2012, 16:38 #2
C++
1
2
private:
    virtual bool Set(int,int) = 0;
чистая виртуальная функция закрыта... либо сделайте защищенной либо открытой

это как вариант
1
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 16:43  [ТС] #3
Всё равно ругается, что 'Point' : cannot instantiate abstract class, вообще с приватной функцией Set() никаких проблем нету, она нормально наследуется и работает и как private и как public, ошибки появляются, когда ввожу новую чисто виртуальную функцию Dist, не могу понять, почему.
0
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
24.08.2012, 16:49 #4
как она принимает в аргументах ссылку на свой тип, если его нельзя создать?
вот тут /*virtual double Dist(const Shape&) = 0; //1. */

на сколько я понял именно об этом и говорится в ошибке
Код
error C2259: 'Point' : cannot instantiate abstract class
1>          due to following members:
1>          'double Shape::Dist(const Shape &)' : is abstract
1
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 16:58  [ТС] #5
Точно, спасибо! То есть нельзя создавать чисто виртуальные функции с указателем на объект абстрактного класса. Значит вообще от этой функции придется отказаться...

Но, кстати, в ошибке все-таки указано на другое, я наконец-то понял. У меня в абстрактном классе функция Dist с аргументом Shape&, а в потомке такая же функция с аргументом Point&, компилятор воспринимает эти функции как разные, полиморфизм не работает, то бишь в моем потомке оказывается две функции:
C++
1
2
virtual double Dist(const Shape&) = 0;
double Dist(const Point&);
А пока в классе Point есть хотя бы одна чисто виртуальная функция, он считается абстрактным и его объекты создавать запрещено.

Только скажите пожалуйста, увидеть воочию все наследованные данные в VS2010 как нибудь можно? Через Class View наследованные данные не отображаются.
0
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
24.08.2012, 17:06 #6
Цитата Сообщение от Martinz Посмотреть сообщение
А пока в классе Point есть хотя бы одна чисто виртуальная функция, он считается абстрактным и его объекты создавать запрещено.
да

Цитата Сообщение от Martinz Посмотреть сообщение
Только скажите пожалуйста, увидеть воочию все наследованные данные в VS2010 как нибудь можно? Через Class View наследованные данные не отображаются.
если я правильно понял
Наследование абстрактного класса, компилятор достал материться
1
4iFF
19 / 19 / 1
Регистрация: 06.07.2012
Сообщений: 88
24.08.2012, 19:05 #7
Martinz, Мое предположение:чистую виртуальную функцию объявить в public,т.к. чисто виртуальную фун-цию в надо инициализировать в производных классах, если она есть в базовом. А как вы это сделаете, если у вас к ней закрытый доступ?

Не по теме:


А так же нельзя создавать объекты абстрактных классов.

0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
24.08.2012, 19:09 #8
4iFF, Без проблем можно.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
class C
{
public:
   virtual ~C() { }
   void call() { func(); }
private:
   virtual void func() = 0;
};
 
class D : public C
{
private:
   void func() { std::cout << "FUNC" << std::endl; }
};
 
int main()
{
   C* c = new D();
   c->call();
   delete c;
}
http://liveworkspace.org/code/73e6451d36a4224262fe1c904975497c
0
defer
秘密
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
24.08.2012, 19:24 #9
Цитата Сообщение от ForEveR Посмотреть сообщение
Без проблем можно.
тут C* c не проверяется, что такое С и сразу создается D, так что пример не годится
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
24.08.2012, 19:27 #10
10.3/3 стандарта, если что. И /2. Переопределение проводится исключительно по имени функции, списку параметров и квалификаторам const/volatile. Область видимости роли не играет. С равным (плачевным) успехом можно (нечаянно) переопределять функции и через десяток классов в иерархии. Именно поэтому не рекомендуется делать private-функции виртуальными.

defer, а что с примером не так? Естественно, экземпляр С создать нельзя. Суть примера в том, что переопределить private виртуальную функцию можно в производных классах без проблем. И даже дать ей другой квалификатор доступа.
1
defer
秘密
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
24.08.2012, 19:33 #11
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
а что с примером не так
показалось
0
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 21:01  [ТС] #12
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Суть примера в том, что переопределить private виртуальную функцию можно в производных классах без проблем. И даже дать ей другой квалификатор доступа.
Кстати спасибо за это интересное уточнение, не знал, что при наследовании можно менять квалификатор доступа, очень во время вы об этом написали. Выходит, если например в базовом абстрактном классе Shape есть виртуальная функция center, вычисляющая центр объекта Shape, которая не имеет смысла в производном классе Point, я переношу её там в private, тем самым запрещая выполнять абсурдную операцию вычисления центра точки, а в классе Line или Circle я оставляю её в public.
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
24.08.2012, 21:09 #13
Martinz, Можно конечно. Только наследовать точку от Shape это простите трындец.
0
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 21:54  [ТС] #14
Цитата Сообщение от ForEveR Посмотреть сообщение
Martinz, Можно конечно. Только наследовать точку от Shape это простите трындец.
Да ну, прям таки трындец) Если Shape это абстрактный объект некоторой формы, почему бы точки, линии, круги и квадраты не отнести к Shape, и затем, например, в массиве Shape* arr[n] хранить указатели на все существующие объекты.
Может название не очень и стоило бы назвать не shape, а graphics или вроде того.
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
24.08.2012, 23:45 #15
Martinz, Точка не является фигурой. Линия является. Разницу улавливаете?
0
24.08.2012, 23:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.08.2012, 23:45
Привет! Вот еще темы с ответами:

Реализация абстрактного класса - C++
Создать абстрактный базовый класс Function (функция) с виртуальными методами вычисления значения функции у = f(x) в заданной точке х и...

Наследники абстрактного класса - C++
Есть классы: class A { public: virtual void met() = 0; }; class B : public A { public: virtual void met() const;

Ошибка компиляции абстрактного класса - C++
public: Tour(); Tour(const char *, int, float); Tour(const Tour &amp;); Tour &amp; operator = (const Tour &amp;) = delete ; ~Tour(); ...

Использование конструктора абстрактного класса - C++
Добрый вечер. Подскажите, как вызвать конструктор абстрактного класса из производного класса? Пытаюсь вызвать так: Advertising*...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

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