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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.73
Merovingean
 Аватар для Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
17.12.2013, 21:45     Обращение к методам класса через указатель на экземпляр класса #1
Добрый день.

Не могу осилить проблему:
Описан абстрактный класс.
Описаны наследники этого класса уже без абстрактности.
Описан контейнер 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 минут
Актуально.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2013, 21:45     Обращение к методам класса через указатель на экземпляр класса
Посмотрите здесь:

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

Добавлено через 2 минуты
Цитата Сообщение от Merovingean Посмотреть сообщение
Соответственно, для дополнительных полей описаны геттеры и сеттеры, которых в базовом классе нет.
Доплнительные методы сделаны? Не виртуальные? Или дополнительный код, для этих полей, сделан в виртуальных методах?
Код покажите. Что вслепую рассуждать.
Merovingean
 Аватар для 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 минуты
Ой. В смысле, объявлены новые методы. Скажем, в базовом всего три поля. Соответственно, для каждого поля есть геттер и сеттер. В производном полей уже четыре. Соответственно, добавлены еще геттер и сеттер для дополнительного поля.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.12.2013, 23:29     Обращение к методам класса через указатель на экземпляр класса #6
Цитата Сообщение от Merovingean Посмотреть сообщение
Как мне вызвать, скажем, setspeed() из класса Cosmic? В то время, как в Шипе его нет.
Никак. Чтобы работал полиморфизм, виртуальные методы должны быть определены и в базовом классе, и в производном. Делайте в базовом классе витруальный метод setspeed(), хоть пустой, тогда всё будет работать.
Цитата Сообщение от Merovingean Посмотреть сообщение
Ой. В смысле, объявлены новые методы. Скажем, в базовом всего три поля. Соответственно, для каждого поля есть геттер и сеттер. В производном полей уже четыре. Соответственно, добавлены еще геттер и сеттер для дополнительного поля.
Для этого не нужно добавлять новый геттер и сеттер. В производном классе переопределяются виртулаьные геттеры и сеттеры базового класса, где и добавляется работа с полями производного класса.
Merovingean
 Аватар для 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) {...}
...
}
При условии, что и в базовом классе есть такие виртуальные чистые функции, а в наследнике они переопределены. В общем, исправно выполняется все, что сказано вами в сообщениях выше.

Как тогда мне вызвать эти самые две функции?
alsav22
5282 / 4801 / 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); // вызов функции производного класса для объекта по первому указателю
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.12.2013, 00:02     Обращение к методам класса через указатель на экземпляр класса
Еще ссылки по теме:

C++ Указатель на объект, или экземпляр класса?
Получение доступа к методам дочернего класса через указатель на родительский, хранимый в vector C++
Обращение к полям и методам класса через объект C++

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

Или воспользуйтесь поиском по форуму:
Merovingean
 Аватар для Merovingean
3 / 3 / 0
Регистрация: 14.12.2013
Сообщений: 67
18.12.2013, 00:02  [ТС]     Обращение к методам класса через указатель на экземпляр класса #9
Большое спасибо.
Вот до этих скобок вокруг итератора я и не додумался.
Yandex
Объявления
18.12.2013, 00:02     Обращение к методам класса через указатель на экземпляр класса
Ответ Создать тему
Опции темы

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