Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
GoldenId
131 / 130 / 64
Регистрация: 11.11.2010
Сообщений: 770
Записей в блоге: 14
Завершенные тесты: 1
#1

Сложение объектов базового и наследуемых классов через виртуальную функцию - C++

01.07.2017, 19:34. Просмотров 164. Ответов 4
Метки нет (Все метки)

Нужно определить базовый класс с виртуальной функцией сложения. Кроме того перегрузка этой же виртуальной функции должна складывать экземпляры классов-наследников. Такое задание. Вроде бы.
Лучшее, что мне пришло в голову:

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
class Base
{
public:
    virtual Base* add( const Base* rhs ) const;
...
};
 
 
class Derived1 : public Base
{
public:
    Base* add( const Base* rhs ) const override;
...
};
 
Base* Base::add( const Base* rhs ) const
{
    if( typeid( *rhs ) != typeid( Base ) )
        throw std::runtime_error(...);
    Base result = new Base(...);
    ...
    return result; // привет, потенциальные утечки памяти
}
 
Base* Derived1::add( const Base* rhs ) const
{
    if( typeid( *rhs ) != typeid( Derived1 ) )
        throw std::runtime_error(...);
    Derived1 result = new Derived1(...);
    ...
    return result; // те же утечки
}
Или можно было бы делать через std::unique_ptr, но в принципе хрен редьки не слаще.

Скажите, это действительно не самое продуманное задание или я туплю?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2017, 19:34
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Сложение объектов базового и наследуемых классов через виртуальную функцию (C++):

Наследование static атрибута(хранение количества объектов наследуемых классов)
Есть абстрактный класс base, от него наследуются 3 класса child1 child2 child3....

Для описанной иерархии классов создать виртуальную функцию
Здравствуйте, прошу помощи. Нужно сделать задание, при этом, вид порождения...

Вызов наследуемых методов из базового класса
Всем доброго времени суток, перейду сразу к сути. Код: class Base { ...

Как через базовый класс вызывать виртуальную функцию во всех потомках?
Ну например, есть класс: class BATYANA { BATYANA(); virtual...

Вызов методов базового и производного классов
Народ, объясните тупому механику раннего связывания. Вывод программы, что ниже,...

Разработать иерархию классов, демонстрирующее работу с коллекцией объектов разных классов
Задание: Разработать в соответствии с индивидуальным заданием иерархию классов...

4
Nemovok
237 / 84 / 86
Регистрация: 30.10.2015
Сообщений: 521
Завершенные тесты: 1
02.07.2017, 03:30 #2
GoldenId, не хотите вернуть из add объект, а не указатель?
0
hoggy
Заблокирован
02.07.2017, 03:46 #3
Цитата Сообщение от Nemovok Посмотреть сообщение
не хотите вернуть из add объект, а не указатель?
и как вы это себе представляете?
0
Nemovok
237 / 84 / 86
Регистрация: 30.10.2015
Сообщений: 521
Завершенные тесты: 1
02.07.2017, 05:08 #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
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
#include <iostream>
 
class Base
{
private:
    int value;
public:
    Base();
    Base( const int v ); 
    virtual Base Add( const Base &b ) const;
    virtual void ShowData() const;
};
 
Base::Base() 
    : value( -1 ) {}
 
Base::Base( const int v ) 
    : value( v )  {} 
 
Base Base::Add( const Base &b ) const
{ return Base( this->value + b.value ); }
 
void Base::ShowData() const 
{ std::cout << value << std::endl; }
 
 
class Derived : public Base
{
private:
    int value_derived;
public:
    Derived();
    Derived( const int v_derived );
    Base Add( const Base &b ) const;
    void ShowData() const;
};
 
Derived::Derived() 
    : Base() {}
 
Derived::Derived( const int v_derived) 
    : Base(), value_derived( v_derived ) {}
 
void Derived::ShowData() const
{ std::cout << this->value_derived << std::endl; }
 
Base Derived::Add( const Base &b ) const
{ 
    // Увы
}
 
int main() 
{ 
    Base b1( 1 );
    Base b2( 2 );
    b1.Add( b2 ).ShowData();
 
    Derived d1( 1 );
    Derived d2( 2 );
    d1.Add( d2 ).ShowData();
}
Добавлено через 6 минут
С базовым классом выходит, а с производным нет(если возвращаю объект Derived, то при сложении выводит не то).
0
GoldenId
131 / 130 / 64
Регистрация: 11.11.2010
Сообщений: 770
Записей в блоге: 14
Завершенные тесты: 1
02.07.2017, 17:47  [ТС] #5
Цитата Сообщение от Nemovok Посмотреть сообщение
GoldenId, не хотите вернуть из add объект, а не указатель?
Хочу. Но так просто это не получается. Можно делать метод add с сигнатурой через двойные ссылки... или как они правильно называются... Видимо, я повторил то, что пытался сделать Nemovok.

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
65
class Base
{
public:
    Base( int param ) : field( param ) {}
    virtual Base&& add( const Base& rhs ) const;
    virtual void out( std::ostream& s ) const;
private:
    int field;
};
 
class Derived1 : public Base
{
public:
    Derived1( double param ) : Base( param ), derived_field( param ) {}
    Base&& add( const Base& rhs ) const override;
    void out( std::ostream& s ) const override;
private:
    double derived_field;
};
 
Base&& Base::add( const Base& rhs ) const
{
    if( typeid( rhs ) != typeid( Base ) )
        throw std::runtime_error( "" );
    return std::forward<Base>( Base( field + rhs.field ) );
}
 
void Base::out( std::ostream& s ) const
{
    s << "Base: " << field;
}
 
 
Base&& Derived1::add( const Base& rhs ) const
{
    if( typeid( rhs ) != typeid( Derived1 ) )
        throw std::runtime_error( "" );
    Derived1 result( derived_field + ( ( Derived1& )rhs ).derived_field );
    return std::forward<Derived1>( result );
}
 
void Derived1::out( std::ostream& s ) const
{
     s << "Derived1: " << derived_field;
}
 
void foo( const Base& a, const Base& b );
 
int main()
{
    Base b1( 1 ), b2( 2 );
    Derived1 d1( 3.14 ), d2( 2.71 );
    foo( b1, b2 );
    foo( d1, d2 );
}
 
void foo( const Base& a, const Base& b )
{
    a.out( std::cout );
    std::cout << " + ";
    b.out( std::cout );
    std::cout << " = ";
    a.add( b ).out( std:: cout );
    std::cout << std::endl;
}
Вывод:
Код
Base: 1 + Base: 2 = Base: 2686024
Derived1: 3.14 + Derived1: 2.71 = Derived1: 6.94928e-308
Объясните.

Добавлено через 4 минуты
Кроме того, можно ли как-то определить operator <<, чтобы можно было сделать и для Base и для Derived1 так:
C++
1
2
3
4
void foo( const Base& a, const Base& b )
{
    std::cout << a << " + " << b << " = " << a.add( b ) << std::endl;
}
?
0
02.07.2017, 17:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2017, 17:47
Привет! Вот еще темы с решениями:

как мне функцию одного класса в функцию базового вставить
как мне функцию одного класса в функцию базового вставить??чет не хера не...

Наследование классов. Доступ к данным базового класса
Здравствуйте! Застрял на задачке... Суть самого задания: Создать класс Car...

Конструирование дочерних классов из базового с private конструктором
Здравствуйте! У меня есть базовый класс для синглтонов, и создание...

Заполнить массив объектов базового класса
Суть задачи: есть базовый класс Участник и производные от него Студент и...


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

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

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