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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.73
Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
#1

Обращение к методам класса через указатель на экземпляр класса - C++

17.12.2013, 21:45. Просмотров 2317. Ответов 8
Метки нет (Все метки)

Добрый день.

Не могу осилить проблему:
Описан абстрактный класс.
Описаны наследники этого класса уже без абстрактности.
Описан контейнер list из STL и описаны итераторы для него.
Элементы контейнера - указатели на экземпляры абс класса.
Контейнер заполнен различными наследниками абс класса.

Задача требует продемонстрировать работу методов классов-наследников для каждого элемента.

Скажем, для каждого наследника описаны методы сеттеров и геттеров
C++
1
2
3
4
5
6
7
8
9
10
11
12
// Например,
void Ship::setname (const char *n)
    {
        delete[]name;
        name = new char[strlen(n) + 1];
        strcpy_s(name, strlen(n) + 1, n);
    }
 
const char* Ship::getname() const
    {
        return name;
    }
Не могли бы вы подсказать, как можно воспользоваться этими методами, имея только указатель на экземпляры базового класса?

Добавлено через 5 часов 27 минут
Актуально.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2013, 21:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обращение к методам класса через указатель на экземпляр класса (C++):

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

Получение доступа к методам дочернего класса через указатель на родительский, хранимый в vector - C++
Была подобная тема с list'ом, но решение, предложенное там, мне не помогло. Соль проблемы заключается в следующем: имеется vector,...

Вызов метода производного класса через обращение к методу базового класса - C++
Добрый день. Изучаю основы ООП, наткнулся на проблему. Если создавать классы внутри main.cpp, то всё нормально. Если же создавать в...

указатель на экземпляр шаблонного класса - C++
имеется такой класс template <class Coord> class Elem { private: const Coord x, y; Elem *Prev; bool check; public: ...

Указатель на текущий экземпляр класса this - C++
Всем здрасьте. Например у меня есть класс: class A { // ... void B(); void C(); // ... }

Указатель на экземпляр шаблонного класса - C++
Есть шаблон класса template <typename TBase> class TArray { ... };, есть некие объекты TArray <A> a; TArray <A> b; TArray <A> c;,...

8
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.12.2013, 21:54 #2
Цитата Сообщение от Merovingean Посмотреть сообщение
для каждого наследника описаны методы сеттеров и геттеров
В базовом есть? Виртуальные?
1
Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
17.12.2013, 22:02  [ТС] #3
Да. Но в некоторых производных классах есть дополнительные поля. Соответственно, для дополнительных полей описаны геттеры и сеттеры, которых в базовом классе нет.
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.12.2013, 22:35 #4
Цитата Сообщение от Merovingean Посмотреть сообщение
Да. Но в некоторых производных классах есть дополнительные поля. Соответственно, для дополнительных полей описаны геттеры и сеттеры, которых в базовом классе нет.
Это понятно... И в чём проблема? Если в контейнере указатели на базовый класс, которые связаны с объектами производных, то, если методы виртуальные, будут вызываться методы производных классов (вызов по типу объекта, а не по типу указателя).

Добавлено через 2 минуты
Цитата Сообщение от Merovingean Посмотреть сообщение
Соответственно, для дополнительных полей описаны геттеры и сеттеры, которых в базовом классе нет.
Доплнительные методы сделаны? Не виртуальные? Или дополнительный код, для этих полей, сделан в виртуальных методах?
Код покажите. Что вслепую рассуждать.
1
Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
17.12.2013, 23:07  [ТС] #5
Проблема в том, что я не знаю, как это написать.
Скажем, я объявляю итератор.
C++
1
list<Ship*>::const_iterator itr;
Как я понимаю, это простейшее обращение к элементу контейнера.
Но там ведь лежит объект не Ship. Там лежит объект типа Cosmic.
Как мне вызвать, скажем, setspeed() из класса Cosmic? В то время, как в Шипе его нет.
Попытки писать itr.setspeed() с разным количеством звездочек в начале ни к чему не приводят.
Пока только в мыслях кустарный способ брать объект из контейнера в отдельную переменную, работать с ним, а результат совать обратно в контейнер по тому же адресу.

Базовый класс.
ClassShip.h
Кликните здесь для просмотра всего текста

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
47
48
49
50
51
#pragma once
#include <iostream>
#include <fstream>
 
using namespace std;
 
class Ship
{
protected:
 
    char *name;     // название
    double capacity;    // вместимость
    int cost;           // стоимость
 
public:
    // Конструкторы, деструктор.
    Ship(void);                                                                                                 // Конструктор по-умолчанию.
    Ship(const Ship & t);                                                                                       // Конструктор копирования.
    Ship(const char *tname, const double &tcap, const int &tcost);  // Конструктор с параметрами.
    virtual ~Ship(void);
    
    // Гет
    virtual const char* getname() const;
    virtual double getcap() const;
    virtual int getcost() const;
    // Сет
    virtual void setname (const char*n);
    virtual void setcap (const double &n);
    virtual void setcost (const int &n);
    
    // Вывод на экран
    virtual ostream & sshow(ostream &t) = 0;
    // Вывод в файл через перегрузку базового класса
    virtual ofstream& fshow(ofstream &t) = 0;
 
    // Перегрузки
    //// Перегрузка вывода
    friend ostream& operator <<(ostream &t, Ship&a);
    friend ofstream& operator <<(ofstream &t, Ship &a);
 
    // Перегрузка операций сравнения
    virtual int cmp(char *x, char *y, int n);
 
    virtual int operator > (const Ship &k);
    virtual int operator < (const Ship &k);
    virtual int operator >= (const Ship &k);
    virtual int operator <= (const Ship &k);
    virtual int operator == (const Ship &k);
    virtual int operator != (const Ship &k);
 
};

// Cosmic.h - один из наследников
Кликните здесь для просмотра всего текста

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
47
48
49
50
51
52
53
54
55
56
57
58
59
#pragma once
#include "ClassShip.h"
#include <iostream>
#include <cstring>
#include <clocale>
#include <fstream>
 
using namespace std;
 
class Cosmic :
    public Ship
{
protected:
    int speed;
 
public:
    // Конструкторы, деструктор.
    Cosmic();
    Cosmic(const Cosmic &a);
    Cosmic(const char *tname, const double &tcap, const int &tcost, const int &tspeed);
    virtual ~Cosmic();
 
    // Вывод на экран через перегрузку базового класса
    virtual ostream & sshow(ostream &t);
    // Вывод в файл через перегрузку базового класса
    virtual ofstream& fshow(ofstream &t);
 
    // Вывод на экран с комментариями.
    virtual void show();
 
    // Вывод на экран с комметариями.
    friend ostream& operator <<(ostream &t, Cosmic&a);
 
    // Вывод в файл.
    friend ofstream& operator <<(ofstream &t, Cosmic&a);
 
    // Гет
    virtual const char* getname() const;
    virtual double getcap() const;
    virtual int getcost() const;
    virtual int getspeed() const;
    // Сет
    virtual void setname(const char*n);
    virtual void setcap(const double &n);
    virtual void setcost(const int &n);
    virtual void setspeed(const int&n);
 
    // Перегрузка операций сравнения
    virtual int cmp(char *x, char *y, int n);
 
    virtual int operator > (const Cosmic &k);
    virtual int operator < (const Cosmic &k);
    virtual int operator >= (const Cosmic &k);
    virtual int operator <= (const Cosmic &k);
    virtual int operator == (const Cosmic &k);
    virtual int operator != (const Cosmic &k);
    
    
};


Добавлено через 2 минуты
Ой. В смысле, объявлены новые методы. Скажем, в базовом всего три поля. Соответственно, для каждого поля есть геттер и сеттер. В производном полей уже четыре. Соответственно, добавлены еще геттер и сеттер для дополнительного поля.
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.12.2013, 23:29 #6
Цитата Сообщение от Merovingean Посмотреть сообщение
Как мне вызвать, скажем, setspeed() из класса Cosmic? В то время, как в Шипе его нет.
Никак. Чтобы работал полиморфизм, виртуальные методы должны быть определены и в базовом классе, и в производном. Делайте в базовом классе витруальный метод setspeed(), хоть пустой, тогда всё будет работать.
Цитата Сообщение от Merovingean Посмотреть сообщение
Ой. В смысле, объявлены новые методы. Скажем, в базовом всего три поля. Соответственно, для каждого поля есть геттер и сеттер. В производном полей уже четыре. Соответственно, добавлены еще геттер и сеттер для дополнительного поля.
Для этого не нужно добавлять новый геттер и сеттер. В производном классе переопределяются виртулаьные геттеры и сеттеры базового класса, где и добавляется работа с полями производного класса.
1
Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
17.12.2013, 23:38  [ТС] #7
Мысль понял.
Если вас не затруднит, не могли бы вы показать, как следует вызывать метод класса?
Скажем, объявлены контейнер и итератор. И где-то там в производном классе есть метод.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// main
list<BaseClass*> A;
list<BaseClass*>::iterator itr;
 
 
// example.h
class MyClass :
    public BaseClass
{
...
virtual int FUNC (int n) {...}
// ну или
virtual MyClass CNUF (const MyClass &a) {...}
...
}
При условии, что и в базовом классе есть такие виртуальные чистые функции, а в наследнике они переопределены. В общем, исправно выполняется все, что сказано вами в сообщениях выше.

Как тогда мне вызвать эти самые две функции?
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.12.2013, 23:58 #8
C++
1
2
3
4
5
list<BaseClass*> A;
list<BaseClass*>::iterator itr;
// здесь list A заполняется указателями на объекты производных классов
itr = A.begin();
(*itr) ->FUNC(5); // вызов функции производного класса для объекта по первому указателю
1
Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
18.12.2013, 00:02  [ТС] #9
Большое спасибо.
Вот до этих скобок вокруг итератора я и не додумался.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.12.2013, 00:02
Привет! Вот еще темы с ответами:

Указатель на объект, или экземпляр класса? - C++
Здравствуйте Уважаемые программисты! Недавно я начал изучать программирование с использованием С++. Ранее не программировал. В качестве...

Обращение к методам базового класса (есть ли подобие base/super?) - C++
Понятное дело, что можно обращаться к методам базового класса так: BaseClass::hisMethod(); Однако это зависимость от названия класса. Не...

Работа с классами (в главном классе создать указатель на экземпляр другого класса) - C++
Недавно начал изучение С++, в частности ООП. В связи с чем у меня есть вопрос как в главном классе можно создать указатель на экземпляр...

Как получить доступ к методам класса, который содержится в векторе класса - C++
Пишу дерево с любым количеством наследников. В классе Thread содержится вектор классов Thread. При попытке просмотра первого элемента в...


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

Или воспользуйтесь поиском по форуму:
9
Yandex
Объявления
18.12.2013, 00:02
Ответ Создать тему
Опции темы

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