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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.77
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 16:31     Наследование абстрактного класса, компилятор достал материться #1
Уже весь мозг сломал, не понимаю, почему компилятор начинает ругаться.
Есть абстрактный базовый класс в отдельном хедере:
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.

Укажите на ошибки пожалуйста, можете потроллить, если это очевидно, только объясните.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.08.2012, 16:31     Наследование абстрактного класса, компилятор достал материться
Посмотрите здесь:

Реализация абстрактного класса C++
C++ Ошибка в создании абстрактного класса
Чем отличается интерфейс от абстрактного класса? C++
C++ Создается объект абстрактного класса:(
C++ Функция абстрактного базового класса
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
24.08.2012, 16:38     Наследование абстрактного класса, компилятор достал материться #2
C++
1
2
private:
    virtual bool Set(int,int) = 0;
чистая виртуальная функция закрыта... либо сделайте защищенной либо открытой

это как вариант
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 16:43  [ТС]     Наследование абстрактного класса, компилятор достал материться #3
Всё равно ругается, что 'Point' : cannot instantiate abstract class, вообще с приватной функцией Set() никаких проблем нету, она нормально наследуется и работает и как private и как public, ошибки появляются, когда ввожу новую чисто виртуальную функцию Dist, не могу понять, почему.
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 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
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 наследованные данные не отображаются.
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
24.08.2012, 17:06     Наследование абстрактного класса, компилятор достал материться #6
Цитата Сообщение от Martinz Посмотреть сообщение
А пока в классе Point есть хотя бы одна чисто виртуальная функция, он считается абстрактным и его объекты создавать запрещено.
да

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

Не по теме:


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

ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 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/73e645...fe1c904975497c
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
24.08.2012, 19:24     Наследование абстрактного класса, компилятор достал материться #9
Цитата Сообщение от ForEveR Посмотреть сообщение
Без проблем можно.
тут C* c не проверяется, что такое С и сразу создается D, так что пример не годится
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
24.08.2012, 19:27     Наследование абстрактного класса, компилятор достал материться #10
10.3/3 стандарта, если что. И /2. Переопределение проводится исключительно по имени функции, списку параметров и квалификаторам const/volatile. Область видимости роли не играет. С равным (плачевным) успехом можно (нечаянно) переопределять функции и через десяток классов в иерархии. Именно поэтому не рекомендуется делать private-функции виртуальными.

defer, а что с примером не так? Естественно, экземпляр С создать нельзя. Суть примера в том, что переопределить private виртуальную функцию можно в производных классах без проблем. И даже дать ей другой квалификатор доступа.
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
24.08.2012, 19:33     Наследование абстрактного класса, компилятор достал материться #11
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
а что с примером не так
показалось
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 21:01  [ТС]     Наследование абстрактного класса, компилятор достал материться #12
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Суть примера в том, что переопределить private виртуальную функцию можно в производных классах без проблем. И даже дать ей другой квалификатор доступа.
Кстати спасибо за это интересное уточнение, не знал, что при наследовании можно менять квалификатор доступа, очень во время вы об этом написали. Выходит, если например в базовом абстрактном классе Shape есть виртуальная функция center, вычисляющая центр объекта Shape, которая не имеет смысла в производном классе Point, я переношу её там в private, тем самым запрещая выполнять абсурдную операцию вычисления центра точки, а в классе Line или Circle я оставляю её в public.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
24.08.2012, 21:09     Наследование абстрактного класса, компилятор достал материться #13
Martinz, Можно конечно. Только наследовать точку от Shape это простите трындец.
Martinz
1 / 1 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 21:54  [ТС]     Наследование абстрактного класса, компилятор достал материться #14
Цитата Сообщение от ForEveR Посмотреть сообщение
Martinz, Можно конечно. Только наследовать точку от Shape это простите трындец.
Да ну, прям таки трындец) Если Shape это абстрактный объект некоторой формы, почему бы точки, линии, круги и квадраты не отнести к Shape, и затем, например, в массиве Shape* arr[n] хранить указатели на все существующие объекты.
Может название не очень и стоило бы назвать не shape, а graphics или вроде того.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
24.08.2012, 23:45     Наследование абстрактного класса, компилятор достал материться #15
Martinz, Точка не является фигурой. Линия является. Разницу улавливаете?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
24.08.2012, 23:58     Наследование абстрактного класса, компилятор достал материться #16
Почему нет? Если считать фигуру множеством точек, то всё окей. А линии вообще можно считать всего лишь парами точек.
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,043
25.08.2012, 00:10     Наследование абстрактного класса, компилятор достал материться #17

Не по теме:

Цитата Сообщение от ForEveR Посмотреть сообщение
Точка не является фигурой.
математически не является
а физически очень маленький круг



Добавлено через 4 минуты
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Если считать фигуру множеством точек, то всё окей.
Цитата Сообщение от ForEveR Посмотреть сообщение
Только наследовать точку от Shape это простите трындец.
ForEveR, прав
какие такие свойства фигуры могут присутствовать в точке???(кроме координат)
логичней наследовать фигуру от точки
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Если считать фигуру множеством точек, то всё окей.
тогда класс точки отдельный а в фигуре массив точек
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.08.2012, 00:11     Наследование абстрактного класса, компилятор достал материться #18
~OhMyGodSoLong~, Ну вообщем да. Но логически наследование Point от Shape кажется несколько странным.
4iFF
 Аватар для 4iFF
19 / 19 / 1
Регистрация: 06.07.2012
Сообщений: 88
25.08.2012, 00:53     Наследование абстрактного класса, компилятор достал материться #19
ForEveR, согласен точка все же не фигура как не крути, так как она нульмерный объект.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.08.2012, 01:04     Наследование абстрактного класса, компилятор достал материться
Еще ссылки по теме:

Деструктор абстрактного класса C++
C++ Использование абстрактного класса
Объекты абстрактного класса C++

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

Или воспользуйтесь поиском по форуму:
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
25.08.2012, 01:04     Наследование абстрактного класса, компилятор достал материться #20
Что значит нульмерный? Нет ширины/высоты/глубины? У прямой их тоже нет. У какого-нибудь открытого множества тоже.

И воще, завязывайте. Это философия всё.
Yandex
Объявления
25.08.2012, 01:04     Наследование абстрактного класса, компилятор достал материться
Ответ Создать тему
Опции темы

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