73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
1

наследование и указатели

05.06.2018, 19:46. Показов 948. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Решается проблема как-нибудь?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <set>
 
class PARENT{};
 
class CHILD : public PARENT{};
 
void some(std::set<PARENT*>*list){}
 
int main(int argc, char**argv)
{
  std::set<CHILD*>somelist;
  some(&somelist);//error C2664: some: невозможно преобразовать параметр 1 из 'std::set<_Kty> *' в 'std::set<_Kty> *'
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.06.2018, 19:46
Ответы с готовыми решениями:

Указатели и наследование С++
Здравствуйте. Помогите, пожалуйста, с указателями. void funcFirst(int *t) { //тут t будет как...

Написать код используя массивы, указатели, виртуальные функции, наследование, классы и т.д
Короче нужно сделать код, программу которая будет использовать массивы, указатели, виртуальные...

указатели и наследование
Есть классы time и oldtime, причем класс time является производным по отношению к классу oldtime,...

Создать сложный класс, используя наследование (указатели, конструкторы и деструкторы)
Создать сложный класс из реальной жизни, используя наследование. В каждом вложенном классе должны...

8
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
05.06.2018, 19:49 2
Множество с PARENT используй везде.
0
Комп_Оратор)
Эксперт по математике/физике
8948 / 4702 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
05.06.2018, 19:53 3
Цитата Сообщение от Praktolock Посмотреть сообщение
Решается проблема как-нибудь?
Зачем std::set<CHILD*>somelist; когда можно std::set<PARENT*>somelist; и добавлять указатели инициализированные и адресами как наследников так и родителя. Только сделай хотябы один виртуальный метод переопределённый в наследнике. В проедельном случае для vtable хватит и виртуального деструктора. Иначе преобразование будет бессмысленно.
ps А вообще, лучше shared использовать потому как с raw тут мороки много.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
05.06.2018, 19:57  [ТС] 4
Цитата Сообщение от IGPIGP Посмотреть сообщение
Зачем std::set<CHILD*>somelist;
Потому что через std::set<PARENT*>somelist мне будет недоступен функционал реализованный в наследнике, очевидно же.
Цитата Сообщение от IGPIGP Посмотреть сообщение
хватит и виртуального деструктора
В приведенном примере нет, а вообще он есть (-:
0
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
05.06.2018, 19:59 5
Цитата Сообщение от Praktolock Посмотреть сообщение
недоступен функционал реализованный в наследнике, очевидно же
Ну сказали же про виртуальность. Или приводи тип.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
05.06.2018, 20:01  [ТС] 6
C++
1
some((std::set<PARENT*>*)&somelist);
Блин, только что компилятор это схавал, я готов поклясться, что час назад такой вариант не компилировался. Совсем что-то голова не варит в 2 ночи. В принципе, такой костыль мне подойдёт.
0
Комп_Оратор)
Эксперт по математике/физике
8948 / 4702 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
05.06.2018, 20:08 7
Цитата Сообщение от Praktolock Посмотреть сообщение
Потому что через std::set<PARENT*>somelist мне будет недоступен функционал реализованный в наследнике
Это неудачная архитектура, в том смысле, что если есть не объявленный в интерфейсе (вирт. методами базового) функционал, то обобщение на уровне указателей бессмысленно. То есть это разные сущности в том смысле в котором их интерфес отличается если эти отличия востребованы. Есть разные способы костылить такие вещи. Писать враперы типа PIMPL например. CRTP паттерн можно попробовать притянуть... А лучше переосмыслить интерфес родителя и если возможно, расширить его так, чтобы у наследника не было проблем (востребованного в коллекции с родственниками функционала недоступного через базовый класс).
На крайний случай остаётся делать таки child* а при добавлении адресов родителя кастовать их. Но потом это станет болью в части выяснения на что именно он смотрит так как вызов несуществующего метода вызовет рантайм ошибку. RTTI придётся юзать (накладно по времени).

Добавлено через 1 минуту
Цитата Сообщение от Praktolock Посмотреть сообщение
В принципе, такой костыль мне подойдёт.
Это указатель на костыль set.
0
"C with Classes"
1644 / 1401 / 523
Регистрация: 16.08.2014
Сообщений: 5,877
Записей в блоге: 1
05.06.2018, 20:10 8
Praktolock, самый крайний вариант, послать систему типов далеко и на долго
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <set>
 
class PARENT {};
 
class CHILD : public PARENT{};
 
void some(std::set<PARENT*>*list){}
 
int main(int argc, char**argv)
{
  std::set<CHILD*>somelist;
  some(reinterpret_cast<std::set<PARENT*>* >(&somelist) );//error C2664: some: невозможно преобразовать параметр 1 из 'std::set<_Kty> *' в 'std::set<_Kty> *'
    return 0;
}
0
Комп_Оратор)
Эксперт по математике/физике
8948 / 4702 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
05.06.2018, 22:17 9
Praktolock, я рискну показать на что это может быть похоже.
сумерки сознания
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
60
61
62
63
64
#include <iostream>
#include <set>
using namespace std;
 
struct Base
{
virtual void virtMetod()
{
    cout<<"\nbaseMetod()\n";
}
    virtual~Base(){}
};
 
struct Child : public Base
{
    virtual void virtMetod()
        {
            cout<<"\nchildMetod()\n";
        }
    virtual void extendedFunctionalBreakingLogics(){cout<<"\ncextendedFunctionalBreakingLogics\n";}
    virtual~Child(){}
};
 
void foo(Base* basePtr, set<Child*> & setBasePtrs)
{
    setBasePtrs.insert(static_cast<Child*>(basePtr));//сказать что это плохо, - ничего не сказать
}
 
template<class FwdIt>
void fooFireVirtual(FwdIt left, FwdIt right){
while(left != right)
    {
        (*left++)->virtMetod();
    }
}
 
template<class FwdIt>
void fooFireExtended(FwdIt left, FwdIt right){//этот код - реально, имменины сердца
    //Мощь RTTI в действии. Не делайте этого!!!
while(left != right)
{
        Base* bp=*left;
        Child* cp = dynamic_cast<Child*>(bp);
        if(cp==0)cout<<"\ncp==0\n";
        else
    (*left)->extendedFunctionalBreakingLogics();    
    ++left;
}
}
 
int main(int argc, char* argv[])
{
    set<Child*>setBasePtrs;
    Base* b1 = new Base();
    Base* b_ch1 = new Child();
    foo(b1, setBasePtrs);
    foo(b_ch1, setBasePtrs);
    fooFireVirtual(setBasePtrs.begin(), setBasePtrs.end());
    cout<<"A teper gorbatiy!";
    fooFireExtended(setBasePtrs.begin(), setBasePtrs.end());
    cout<<endl;
system("pause");
return 0;
}

Ну то есть, лучше бы базовый объявлял виртуально и второй метод. Иначе коллекция таких указателей - противоестественна и работать с ней плохо.
0
05.06.2018, 22:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.06.2018, 22:17
Помогаю со студенческими работами здесь

Указатели и указатели на указатели, а также типы данных
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно....

Через указатели на указатели посчитать сумму двух чисел и записать в третье
1. Через указатели на указатели посчитать сумму двух чисел и записать в третье. 2. Написать...

В matlab есть указатели на переменные или что-нибудь похожее на указатели?
Здравствуйте, в matlab есть указатели на переменные? или что-нибудь похожее на указатели? нужно...

Почему Лафоре использует указатели на указатели, вместо обмена значениями указателей?
Доброго времени суток! Задался теоретическим вопросом. Читал пример из книги Лафоре...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

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