117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
1

Приведение производного типа к предку

02.11.2015, 15:32. Показов 2268. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть класс-обертка Inherit, есть класс Base:
C++
1
2
3
4
5
6
7
8
class Inherit : public Base
{
public:
   int c;
   Inherit(int a, b, _c)
   : Base(a, b), c(_c)
   {}
};
Как видно, добавился лишь новый конструктор, ничего более.

Есть некоторые функции, которые принимают объект Base, есть другие, которые принимают потомка. Но как я понял, нужно перегружать функции для обоих классов.
Вот и вопрос: можно ли обойтись единственными реализациями функций, чтобы они работали с объектами как базового, так и производного класса, но только без указателей?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.11.2015, 15:32
Ответы с готовыми решениями:

Приведение переменной типа object к переменной производного типа в приложенном коде
Добрый день! Столкнулся с проблемой. Есть обработчик события. Обработчик события общий для двух...

Передача типа из производного класса в родительский
Добрый день! Есть код: template<typename T> struct Base { void test(typename T::Axis aaa)...

Приведение типа без имени типа?
У меня есть данные о типе, полученные через typeof, как можно приводить к типу от которого был...

Ссылается ли на экземпляр производного класса переменная родительского типа в приведенном коде
Гербердт Шилдт не поленился, два раза повторил: "по ссылке на объект базового класса можно...

18
Эксперт С++
4982 / 3089 / 456
Регистрация: 10.11.2010
Сообщений: 11,165
Записей в блоге: 10
02.11.2015, 15:49 2
C++
1
2
3
4
5
template <typename T>
void foo( T & t ) {
    static_assert( std::is_base_of<Base, T>::value, "T is not derived from Base" );
    ...
}
1
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
02.11.2015, 16:10  [ТС] 3
castaway, хм, про шаблоны забыл упомянуть в конце. Впрочем, можно и ими обойтись.

В общем, спокойно кастовать не выйдет?
0
7527 / 6392 / 2914
Регистрация: 14.04.2014
Сообщений: 27,850
02.11.2015, 16:14 4
Это попытка сэкономить, что ли? Если у тебя классы в иерархии не различаются, зачем ты её придумал?
Если функция работает только с полями, которые есть у предка, то используй параметр базового класса, он же совместим с потомками (ссылку, не указатель).
0
Эксперт С++
4982 / 3089 / 456
Регистрация: 10.11.2010
Сообщений: 11,165
Записей в блоге: 10
02.11.2015, 16:17 5
Лучший ответ Сообщение было отмечено tnk500 как решение

Решение

Хотя подожди...
Можно использовать ссылку, если тебя не устраивает указатель.
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
#include <iostream>
 
struct A {
    virtual void foo() { std::cout << "A::foo()\n"; }
};
 
struct B : A {
    void foo() { std::cout << "B::foo()\n"; }
};
 
struct C {
    void foo() { std::cout << "C::foo()\n"; }
};
 
void bar( A & a ) {
    a.foo();
}
 
int main() {
    A a;
    B b;
    C c;
    bar( a );
    bar( b );
    //bar( c ); // fail
}
Цитата Сообщение от tnk500 Посмотреть сообщение
В общем, спокойно кастовать не выйдет?
Что ты имеешь в виду?
1
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
02.11.2015, 16:22 6
Цитата Сообщение от tnk500 Посмотреть сообщение
но только без указателей?
и в чем понт?
указатель какбэ и дает использовать полиморфизм. потому что указатель всегда одинаковый - 4/8байт
если не работать с указателями, то не работают виртуальные функции, интерфейсы, автоматические преобразования потомка к предку.

Совет: поменять архитектуру
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
02.11.2015, 16:28  [ТС] 7
castaway, великолепно, то, что нужно. Благодарю.

Добавлено через 1 минуту
Цитата Сообщение от nmcf Посмотреть сообщение
Это попытка сэкономить, что ли? Если у тебя классы в иерархии не различаются, зачем ты её придумал?
Цитата Сообщение от Fallenworld Посмотреть сообщение
и в чем понт?
Просто интересно. Нельзя поинтересоваться?

Добавлено через 2 минуты
Цитата Сообщение от castaway Посмотреть сообщение
Что ты имеешь в виду?
Мне нужен доступ к полю наследника, поэтому я ожидал что-то вроде передачи ссылки и кастования объекта базового класса до наследника с целью получить доступ. Здесь мне кажется, просто так получить к нему доступ не выйдет, так что кастовать-таки придется. В общем, проверю. Сейчас просто другим был занят, проверить эту теорию просто времени не было.
0
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
02.11.2015, 16:30 8
Цитата Сообщение от tnk500 Посмотреть сообщение
Нельзя поинтересоваться?
а, ок. Вот какраз эти размышления и привели к указателям когдато)

Добавлено через 1 минуту
Цитата Сообщение от tnk500 Посмотреть сообщение
Мне нужен доступ к полю наследника, поэтому я ожидал что-то вроде передачи ссылки и кастования объекта базового класса до наследника с целью получить доступ.
сделай виртуальный метод getField();
доступ ко всем членам класса надо делать через методы, чтобы класс "знал" когда его данные читают, смекаешь?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
02.11.2015, 18:51 9
Цитата Сообщение от tnk500 Посмотреть сообщение
ак что кастовать-таки придется
для этого придуман dynamic_cast<>
0
Эксперт С++
8724 / 4304 / 958
Регистрация: 15.11.2014
Сообщений: 9,751
02.11.2015, 20:03 10
Цитата Сообщение от tnk500 Посмотреть сообщение
чтобы они работали с объектами как базового, так и производного класса, но только без указателей?
можно. и даже нужно.
используйте ссылку на базовый класс.


Цитата Сообщение от Fallenworld Посмотреть сообщение
и в чем понт?
в том, что работа с полиморфом предполагает наличие валидного живого объекта.

а значит нет ни одной причины для того,
что бы использовать указатели там,
где безопаснее и лучше по смыслу подходят ссылки.

Цитата Сообщение от Fallenworld Посмотреть сообщение
если не работать с указателями, то не работают виртуальные функции
все там работает.
0
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
02.11.2015, 20:14 11
Цитата Сообщение от hoggy Посмотреть сообщение
спользовать указатели там,
где безопаснее и лучше по смыслу подходят ссылки
сылка не константный указатель, не?

Добавлено через 4 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
все там работает.
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
class Base{
   public:
    virtual void out(){
        cout<<"base"<<endl;
    }
};
class Derived:public Base{
public:
    virtual void out(){
        cout<<"derived"<<endl;
    }
};
 
int main()
{
    Base a;
    Base *pa;
    Derived d;
    a = d;
    pa = &d;
    a.out();
    pa->out();
 
    return 0;
}
0
castaway
02.11.2015, 20:14
  #12

Не по теме:

Цитата Сообщение от Fallenworld Посмотреть сообщение
сылка не константный указатель, не?
о_О

0
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
02.11.2015, 20:20 13
ну и да
C++
1
2
 Base &ba = d;
    ba.out();
работает, но это указатель, все равно. Пусть в с++ он компиллятором обрабатывается не совсем как const Base *, но всетаки это указатель, и арифметика будет как у указателей

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от castaway Посмотреть сообщение
о_О
что?

0
castaway
02.11.2015, 20:34
  #14

Не по теме:

Цитата Сообщение от Fallenworld Посмотреть сообщение
что?
Нет.

0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
02.11.2015, 20:42 15
Цитата Сообщение от Fallenworld Посмотреть сообщение
и арифметика будет как у указателей
Арифметика ссылок? Ссылка - это альтернативное имя объекта. Для ссылки нельзя использовать, например, инкремент, если он не реализован для объекта типа. А вот для указателя можно, независимо от того, реализован он в классе или нет.
0
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
02.11.2015, 20:56 16
Цитата Сообщение от Tulosba Посмотреть сообщение
Арифметика ссылок? Ссылка - это альтернативное имя объекта. Для ссылки нельзя использовать, например, инкремент, если он не реализован для объекта типа. А вот для указателя можно, независимо от того, реализован он в классе или нет.
Ну нет.
A &a == const A*a;
нельзя инкремент. Нельзя неинициализированный создать.
0
Эксперт С++
4982 / 3089 / 456
Регистрация: 10.11.2010
Сообщений: 11,165
Записей в блоге: 10
02.11.2015, 21:07 17
Цитата Сообщение от Fallenworld Посмотреть сообщение
A &a == const A*a;
Так всё-таки константный указатель, или указатель на константу?
0
Эксперт С++
8724 / 4304 / 958
Регистрация: 15.11.2014
Сообщений: 9,751
02.11.2015, 21:14 18
Цитата Сообщение от Fallenworld Посмотреть сообщение
сылка не константный указатель, не?
не.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Base{
* *public:
* * virtual void out(){
* * * * cout<<"base"<<endl;
* * }
};
class Derived:public Base{
public:
* * virtual void out(){
* * * * cout<<"derived"<<endl;
* * }
};
int main()
{
* * Base a;
* * Base *pa;
* * Derived d;
* * a = d;           //<--- срезка
* * pa = &d;
* * a.out();
* * pa->out();
return 0;
}
заменить на:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Base{
   public:
    virtual void out(){
        cout<<"base"<<endl;
    }
};
class Derived:public Base{
public:
    virtual void out(){
        cout<<"derived"<<endl;
    }
};
 
int main()
{
    Derived d;
    Base& a = d;
    a.out();
}
Добавлено через 1 минуту
Цитата Сообщение от Fallenworld Посмотреть сообщение
работает, но это указатель, все равно.
ну заблуждайтесь дальше, чоу.
0
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
03.11.2015, 14:42 19
Цитата Сообщение от castaway Посмотреть сообщение
Так всё-таки константный указатель, или указатель на константу?
я хотел бы сказать, что это опечатка, но черт побери я действительно думал, что пишется так.
константный указатель
Base * const ptr;
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.11.2015, 14:42
Помогаю со студенческими работами здесь

Конструкторы, приведение типа и ошибка "Не найден оператор, принимающий правый операнд типа 'char *'"
#include &lt;stdio.h&gt; class A { int somemember; public: A(){printf(&quot;A()\n&quot;);} ...

приведение типа
Здравствуйте. у меня такой вопрос. как можно в c++ 2008 поменять тип. мне нужно char перевести в...

Приведение типа
Как преобразовать тип QStringList к типу int ? Добавлено через 7 минут Проблема решена

Приведение типа
Здравствуйте. int i = 257; byte b; b = (byte) i; ...


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

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

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