Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
140 / 141 / 64
Регистрация: 11.11.2010
Сообщений: 863
Записей в блоге: 10
1

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

01.07.2017, 19:34. Просмотров 761. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.07.2017, 19:34
Ответы с готовыми решениями:

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

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

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

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

4
294 / 123 / 106
Регистрация: 30.10.2015
Сообщений: 690
02.07.2017, 03:30 2
GoldenId, не хотите вернуть из add объект, а не указатель?
0
Эксперт С++
8388 / 3930 / 857
Регистрация: 15.11.2014
Сообщений: 8,868
02.07.2017, 03:46 3
Цитата Сообщение от Nemovok Посмотреть сообщение
не хотите вернуть из add объект, а не указатель?
и как вы это себе представляете?
0
294 / 123 / 106
Регистрация: 30.10.2015
Сообщений: 690
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
140 / 141 / 64
Регистрация: 11.11.2010
Сообщений: 863
Записей в блоге: 10
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.07.2017, 17:47

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Из трех наследуемых классов получить массив родителя
Всем мира! Не один раз вы меня выручали, помогите, пожалуйста и в этот раз. Расту. И вопросы...

Как правильно реализовать событие и подписку на него через несколько наследуемых классов?
Всё еще работаю над игрой Морской Бой в свободное время. И есть у меня такая структура: Game class,...

Занести из файла объекты производных классов в массив объектов базового класса
Здравствуйте. Что в этом коде изменить, чтобы объекты производных классов заносились из файла?...

Список наследуемых классов
Здравствуйте. Скажите пожалуйста можно ли получить список всех классов, которые наследуются от...


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

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

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