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

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

Войти
Регистрация
Восстановить пароль
 
JackLas
2 / 2 / 0
Регистрация: 17.12.2015
Сообщений: 102
Завершенные тесты: 2
#1

Научить метод принимать в качестве аргумента объект своего класса и дочерних классов - C++

09.07.2016, 17:40. Просмотров 481. Ответов 14
Метки нет (Все метки)

Как научить метод принимать в качестве аргумента объект своего класса и дочерних классов? Как их передавать при вызове метода?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.07.2016, 17:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Научить метод принимать в качестве аргумента объект своего класса и дочерних классов (C++):

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

Указатель на метод класса в качестве аргумента метода класса - C++
Функция _createFun вызывается для создания ХХХ в основном классе. Но вот потребовалось создать ХХХ в дополнительном классе. Вопрос: как...

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра? - C++
header.h template <class T> class MyVector { public: void swap(MyVector<T>Vector); } template <class T> void...

Какого типа std::endl ? Как сделать так, чтобы функция могла принимать endl в качестве аргумента? - C++
Что надо указать в прототипе функции, чтобы можно передавать std::endl в качестве аргумента? Уже 3 часа голову ломаю! :wall: Помогите,...

Конструктор, принимающий в качестве аргумента ссылку на объект, всё портит - C++
Друзья! Вот корректный код: class foo { public: foo() { } ...

Использование в качестве поля класса указатель на объект другого класса - C++
Ошибка в названии - "указателЯ" Вот, пытаюсь освоить ООП (пока только учусь): создаю класс person (человек) и car (модель машины). ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
shilko2013
240 / 217 / 117
Регистрация: 02.04.2016
Сообщений: 827
Завершенные тесты: 1
09.07.2016, 17:44 #2
по ссылке, если это то, что я подумал.
C++
1
2
3
class Class {
public: Metod (Class & a);
}
JackLas
2 / 2 / 0
Регистрация: 17.12.2015
Сообщений: 102
Завершенные тесты: 2
09.07.2016, 20:36  [ТС] #3
Цитата Сообщение от shilko2013 Посмотреть сообщение
public: Metod (Class & a);
Зачем & ?
Anglues113
0 / 0 / 0
Регистрация: 09.07.2016
Сообщений: 5
09.07.2016, 21:55 #4
Цитата Сообщение от JackLas Посмотреть сообщение
Зачем & ?
Method (class & a) - это значит что вы передаете объект по ссылке и имеете дело с существующим объектом.
Mehod (class a) - будет сделана локальная копия объекта и её изменение не будет влиять на объект который был передан в этой функции.
А вообще наследники родительского класса приобретают все свойства и методы родительского класса. И объект производного класса можно смело передавать в метод который принимает ссылку на базовый класс.

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
#include <iostream>
 
using namespace std;
 
class A
{
    int x;
public:
    void Method(A & a, const int & i)
    {
        this->x = i;
        std::cout << this->x << std::endl;
    }
};
 
class B : public A
{
 
};
 
int main()
{
    A a;
    a.Method(a, 10);
    B b;
    b.Method(b, 20);
}

Так же можно сделать метод виртуальным и переопределить его в наследниках. Он станет полиморфным при вызове через указатель базового класса. Вариантов много все зависит от того что конкретно надо

Добавлено через 14 минут
Цитата Сообщение от Anglues113 Посмотреть сообщение
this->x = i;
В этом месте написать -
C++
1
 a.x = i;
и оно будет работать
Unknownx
Заблокирован
09.07.2016, 21:59 #5
Цитата Сообщение от JackLas Посмотреть сообщение
Как научить метод принимать в качестве аргумента объект своего класса и дочерних классов? Как их передавать при вызове метода?
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
#include <string>
#include <iostream>
using namespace std;
 
class parrent{
    public:
    virtual ~parrent(){}
    static string info(parrent *obj = 0){
        string name;
        parrent * ptr = dynamic_cast< parrent *>(obj);
        if( ptr != 0 )
            name = typeid(*obj).name();
        return name; 
    }
};
 
class child1 : public parrent{};
class child2 : public child1 {};
 
int main(){
    parrent p;
    child1  ch1;
    child2  ch2;
    cout<<parrent::info(&p)<<endl;
    cout<<parrent::info(&ch1)<<endl;
    cout<<parrent::info(&ch2)<<endl;
    return 0;
}
http://codepad.org/U55N0i2U
7parrent
6child1
6child2

Не по теме:

Добавлено через 3 минуты
Anglues113, как ты собрался отличать классы без кастования?
http://codepad.org/DOHS6b0i

DrOffset
7089 / 4230 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
09.07.2016, 22:40 #6
Цитата Сообщение от Unknownx Посмотреть сообщение
отличать классы
В нормальном режиме это и не требуется. Полиморфизм покрывает почти все кейсы.
Unknownx
10.07.2016, 08:39
  #7

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
В нормальном режиме это и не требуется. Полиморфизм покрывает почти все кейсы.
- хорошо перефразирую, пришёл указатель на базовый класс, для моего примера как понять что это child1 а не child2 без dynamic_cast?Опять же слово почти != всё

Melg
538 / 159 / 64
Регистрация: 23.09.2013
Сообщений: 314
10.07.2016, 10:05 #8
Unknownx, в общем случае попытка выяснить тип объекта по ссылке на базовый класс говорит о каких-то проблемах в архитектуре. Идея полиморфизма заключается в том, что в наследниках класса находится код, который привязан к типу этого наследника и делает в соответствии со своим специфическим знанием что-то отличное от других наследников. При этом код, который использует указатель/ссылку на базовый класс должен работать с ним как с целостной сущностью и ни в коем случае НЕ должен начинать зависеть от того, какой на самом деле наследник базового класса был проброшен при вызове, а наследник должен реализовывать функциональность в соответсвии с заявленной в базовом классе (принцип подстановки Лисков (LSP из SOLID). Если говорить о некоторых более частных случаях, скажем в виде исключения - то может использоваться либо двойная диспетчеризация - когда с одной стороны используется полиморфизм для обработки вызова, с другой стороны вызываются разные перегрузки методов исходя из типа аргумента (Таким образом устроен boost::static_visitor для boost::variant). Наконец если используются техники типа type erasure и по какой-то причине понадобилось знать какой тип действительно находится за концепцией any/type_erasure/variant могут использоваться либо подходы с кастами ( в том числе специфические для данного типа, а не dynamic_cast, например как в any_cast). Ну и самый прямолобый вариант - просто иметь метод, который возвращает тип хранимого в базовом классе наследника (как например реализовано в QVariant::type). Если Вы приведете конкретный пример задачи, решение которой Вас интересует с точки зрения использования полиморфизма, мы могли бы подумать над тем, можно ли найти её решение без попыток выяснения типа наследника в пользователе базового класса.
Unknownx
Заблокирован
10.07.2016, 10:48 #9
Цитата Сообщение от Melg Посмотреть сообщение
Unknownx, в общем случае попытка выяснить тип объекта по ссылке на базовый класс говорит о каких-то проблемах в архитектуре.
- глупость. Пример : я могу использовать кросс-платформенный фрейморк, в котором к примеру есть класс канвы привязанный к конкретной платформе, к примеру под маком будет макканва, под убунтой - убунтуканва, под вин винканва, каждая канва в силу различия плафторм имеет свои особенности при этом имеет общую сущность, мой рендерер должен распознать какая канва к нему пришла, а может и ноль прийти(или ты всё дефанами будешь разруливать делая спагетти код, м? Что по твоему лучше - 3 платформоспецифических канвы в разных либах или одна с 3 типами #ifdef). Думаю ты просто привык максим к виртуальным методам, а я привык работать без КуТэ сразу под несколькими осями, так что надеюсь понятно почему я написал глупость на твои слова.
Melg
538 / 159 / 64
Регистрация: 23.09.2013
Сообщений: 314
10.07.2016, 10:57 #10
Unknownx, Не смотря на Ваш, мягко говоря, своеобразный способ общения, мне было бы интересно узнать действительно ли Ваше положение не удастся спасти никак кроме как через выяснение типа наследника. Вы можете привести минимальный пример кода, который бы воспроизводил ситуацию? (Вот с теми же канвами) потому-что из Ваших слов мне не понятно о каких "особенностях" в канвах идет речь, и как они при этом используются в рендере. (Если у вас есть opensource проект иллюстрирующий проблему - я могу взглянуть и на него).
Unknownx
10.07.2016, 11:07
  #11

Не по теме:

Melg, очень много проприетарного кода. Лучше останемся каждый при своём мнении.

Melg
10.07.2016, 11:21
  #12

Не по теме:

Unknownx, тогда Ваши заявления мягко говоря голословны. В зависимости от того в чем заключались эти различия между канвами - сигнатуры методов, названия методов, наличие дополнительных методов настроек, разное поведение одних и тех же методов, и т.д. и тем как именно и для чего использует их рендер - по-разному бы звучал ответ на тему того как именно можно решать такую задачу с/без использованием знаний о типе конвы. Вопрос про #ifdef-ы к полиморфизму имеет чуть больше чем нисколько отношения, поскольку директивы препроцессора вообще на другом этапе выполняются. В общем случае я бы предпочел видеть разделенные реализации, которые тем или иным образом (pimpl, переопределение символов, подгрузка отдельной либы, условная компиляция разных единиц трансляции под платформу) объединяются под общим интерфейсом (классов/методов/функций) c которым везде в системе можно работать единым образом БЕЗ необходимости дописывать платформозависимый код в вышестоящие классы-пользователи. Возможно между платформозависимым кодом и пользователями в Вашем случае отсутствует необходимый слой адаптеров, который бы с одной стороны работал непосредственно со знанием конкретной платформы, с другой стороны - пользователям предоставлял унифицированный интерфейс с единообразным поведением под всеми платформами.

Unknownx
10.07.2016, 11:57
  #13

Не по теме:

Цитата Сообщение от Melg Посмотреть сообщение
Unknownx, тогда Ваши заявления мягко говоря голословны.
я ничего другого в твоём ответе и не ожидал услышать. За своим псевдоначитанным стилем письма(обычно его применяют чтобы замаскировать довольно низкий уровень знаний) я пока вижу весьма заурядного кодера, которому видимо доставляет удовольствие поругаться на форуме, видимо с самооценкой не сложилось, пока...

Renji
1901 / 1299 / 291
Регистрация: 05.06.2014
Сообщений: 3,711
10.07.2016, 12:20 #14
Цитата Сообщение от Melg Посмотреть сообщение
Unknownx, Не смотря на Ваш, мягко говоря, своеобразный способ общения, мне было бы интересно узнать действительно ли Ваше положение не удастся спасти никак кроме как через выяснение типа наследника.
Судя по упоминанию ifdef и дефайнов, у него там условная компиляция, а не выяснение типа объекта на стадии исполнения.
avgoor
884 / 519 / 112
Регистрация: 05.12.2015
Сообщений: 1,465
10.07.2016, 16:41 #15
Цитата Сообщение от Unknownx Посмотреть сообщение
- глупость. Пример : я могу использовать кросс-платформенный фрейморк, в котором к примеру есть класс канвы привязанный к конкретной платформе, к примеру под маком будет макканва, под убунтой - убунтуканва, под вин винканва, каждая канва в силу различия плафторм имеет свои особенности при этом имеет общую сущность, мой рендерер должен распознать какая канва к нему пришла, а может и ноль прийти(или ты всё дефанами будешь разруливать делая спагетти код, м? Что по твоему лучше - 3 платформоспецифических канвы в разных либах или одна с 3 типами #ifdef). Думаю ты просто привык максим к виртуальным методам, а я привык работать без КуТэ сразу под несколькими осями, так что надеюсь понятно почему я написал глупость на твои слова.
У нас будет свой фреймворк! С полиморфизмом и абстракциями! И, таки, навелосипедили. Только с абстракциями косячок вышел: оказались очень страшными, поэтому все чаще приходится заниматься полиморфизмом в клиентском коде, аж руки стерли. Сопровождается использованием dynamic_cast вместо виртуальных методов. И еще что-то говорят про спагетти код.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2016, 16:41
Привет! Вот еще темы с ответами:

Как создать шаблон класса, который сможет принимать в качестве значения любые stl контейнеры - C++
Как написать класс, в который можно засунуть vector&lt;int&gt;, или vector&lt;float&gt;, или deque&lt;double&gt; и т.д?

Передача матрицы в метод в качестве аргумента - C++
Доброе время суток! Ребят забыл когда последний раз это делал, и вот косяки, ткните носом где я наложал! Код: #include &lt;iostream&gt;...

Передача enum в качестве аргумента метода класса - C++
Есть класс //class order; class ticket{ enum type_of_place { coupe, general, berth, wagon_lit }_type_of_place; char*...

Передача метода класса в качестве аргумента внешней функции - C++
Столкнулся со следующей проблемой. Пусть у меня есть некая внешняя функция, которая принимает в качестве аргумента указатель на функцию...


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

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

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