Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.84/19: Рейтинг темы: голосов - 19, средняя оценка - 4.84
3 / 3 / 0
Регистрация: 04.01.2011
Сообщений: 37
1

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

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

Author24 — интернет-сервис помощи студентам
Уже весь мозг сломал, не понимаю, почему компилятор начинает ругаться.
Есть абстрактный базовый класс в отдельном хедере:
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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.08.2012, 16:31
Ответы с готовыми решениями:

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

Наследование от абстрактного класса.
В общем есть абстрактный класс: abstract class SkyObject { /* поля. свойства*/ ...

Наследование от абстрактного класса
Приветствую. Есть несколько классов, и у них есть операция сложения. При этом каждый метод своего...

Можно ли реализовать наследование абстрактного класса
Можно ли на шарпе реализовать наследование абстрактного класса двумя независимыми друг от друга...

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

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

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

Не по теме:


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

0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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/... 904975497c
0
577 / 256 / 18
Регистрация: 29.11.2010
Сообщений: 868
24.08.2012, 19:24 9
Цитата Сообщение от ForEveR Посмотреть сообщение
Без проблем можно.
тут C* c не проверяется, что такое С и сразу создается D, так что пример не годится
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
24.08.2012, 19:27 10
10.3/3 стандарта, если что. И /2. Переопределение проводится исключительно по имени функции, списку параметров и квалификаторам const/volatile. Область видимости роли не играет. С равным (плачевным) успехом можно (нечаянно) переопределять функции и через десяток классов в иерархии. Именно поэтому не рекомендуется делать private-функции виртуальными.

defer, а что с примером не так? Естественно, экземпляр С создать нельзя. Суть примера в том, что переопределить private виртуальную функцию можно в производных классах без проблем. И даже дать ей другой квалификатор доступа.
1
577 / 256 / 18
Регистрация: 29.11.2010
Сообщений: 868
24.08.2012, 19:33 11
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
а что с примером не так
показалось
0
3 / 3 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 21:01  [ТС] 12
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Суть примера в том, что переопределить private виртуальную функцию можно в производных классах без проблем. И даже дать ей другой квалификатор доступа.
Кстати спасибо за это интересное уточнение, не знал, что при наследовании можно менять квалификатор доступа, очень во время вы об этом написали. Выходит, если например в базовом абстрактном классе Shape есть виртуальная функция center, вычисляющая центр объекта Shape, которая не имеет смысла в производном классе Point, я переношу её там в private, тем самым запрещая выполнять абсурдную операцию вычисления центра точки, а в классе Line или Circle я оставляю её в public.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
24.08.2012, 21:09 13
Martinz, Можно конечно. Только наследовать точку от Shape это простите трындец.
0
3 / 3 / 0
Регистрация: 04.01.2011
Сообщений: 37
24.08.2012, 21:54  [ТС] 14
Цитата Сообщение от ForEveR Посмотреть сообщение
Martinz, Можно конечно. Только наследовать точку от Shape это простите трындец.
Да ну, прям таки трындец) Если Shape это абстрактный объект некоторой формы, почему бы точки, линии, круги и квадраты не отнести к Shape, и затем, например, в массиве Shape* arr[n] хранить указатели на все существующие объекты.
Может название не очень и стоило бы назвать не shape, а graphics или вроде того.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
24.08.2012, 23:45 15
Martinz, Точка не является фигурой. Линия является. Разницу улавливаете?
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
24.08.2012, 23:58 16
Почему нет? Если считать фигуру множеством точек, то всё окей. А линии вообще можно считать всего лишь парами точек.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,519
25.08.2012, 00:10 17

Не по теме:

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



Добавлено через 4 минуты
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Если считать фигуру множеством точек, то всё окей.
Цитата Сообщение от ForEveR Посмотреть сообщение
Только наследовать точку от Shape это простите трындец.
ForEveR, прав
какие такие свойства фигуры могут присутствовать в точке???(кроме координат)
логичней наследовать фигуру от точки
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Если считать фигуру множеством точек, то всё окей.
тогда класс точки отдельный а в фигуре массив точек
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
25.08.2012, 00:11 18
~OhMyGodSoLong~, Ну вообщем да. Но логически наследование Point от Shape кажется несколько странным.
0
21 / 21 / 1
Регистрация: 06.07.2012
Сообщений: 88
25.08.2012, 00:53 19
ForEveR, согласен точка все же не фигура как не крути, так как она нульмерный объект.
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
25.08.2012, 01:04 20
Что значит нульмерный? Нет ширины/высоты/глубины? У прямой их тоже нет. У какого-нибудь открытого множества тоже.

И воще, завязывайте. Это философия всё.
0
25.08.2012, 01:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.08.2012, 01:04
Помогаю со студенческими работами здесь

Задача на наследование с использованием абстрактного класса
Разработать базовый класс Commodity, описывающий товар. Поля: название товара; цена в рублях....

Как компилятор различает две перегрузки метода абстрактного класса в инстанцированном классе потомке?
using System; namespace ConsoleApp1 { public abstract class cl&lt;T&gt; { public abstract void...

Запрет наследование абстрактного метода
Абстрактный класс ValueType наследует от Object-a Только 3 метода, или наследует все но видны 3...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru