【问题标题】:How to create list that contains multiple types of objects in C++如何在 C++ 中创建包含多种类型对象的列表
【发布时间】:2021-03-21 13:09:59
【问题描述】:

场景:

我正处于使用 C++ 进行 OOP 的设计阶段。我只想设计一个有四种动作的移动动作。这些动作具有相同的共同变量和功能。这些类也有一些离散变量和函数。位于 Class_Action(基类)中的相同函数和变量。

下面给出的其他四种类型的动作都继承了 Class_Action。

class Class_Action_Action_Type_A : public Class_Action 

class Class_Action_Action_Type_B : public Class_Action 

class Class_Action_Action_Type_C : public Class_Action 

class Class_Action_Action_Type_D : public Class_Action 

我想将所有移动动作保存在一个泛型类型为 Class_Move 的列表中。 Class_Move 继承所有 Action 类型。它错误为“没有重载函数的实例计算参数列表。”

我有以下问题:

1-) 我如何申请上述状态?

2-) 如您所知,如果我从 Class_Move 继承所有四个动作类,则 Class_Move 的每个初始化都包含其他类成员(函数和变量)。例如,当我到达作为 Class_Move 的元素时,我想将 Action_Type_A 添加到 Class_Move,它包含位于 Action_Type_B 中的 set_action_type_B_time 变量。如何避免参数冗余?

3-) 用 OOP 设计这些问题的最佳方法是什么。

4-) 在这种情况下可以使用哪种设计模式? (我正在尝试应用 Builder Pattern)

谢谢,

我有以下课程:

-------------------------------------------------------------------------
Class_Action.h :

class Class_Action
{
protected:
    float action_time_f32;               
    float battery_consumption_result_f32;    
    float battery_consumption_value_f32;                                             
public:

    Class_Action                             ();

    void     update_vehicle_current_altitude ();
    void     set_battery_consumption_value   (float p_battery_consumption_value); 
    void     set_battery_consumption_result  (float p_battery_consumption_result);
    void     set_Action_time                 (float p_action_time);

    float    calc_battery_consumption        ();
    float    get_battery_consumption_value   ();
    float    get_battery_consumption_result  ();
    float    get_action_time                 ();

};
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Class_Action_Action_Type_A.h :

class Class_Action_Action_Type_A : public Class_Action 
{
private:
    float  end_point_f32;       
    float  start_point_f32;                                
    float  action_type_A_rate_f32;         
public:
    Class_Action_Action_Type_A                   ();
    Class_Action_Action_Type_A                   (float battery_consumption_value_f32,
                                                  float action_type_A_rate_f32,
                                                  float start_point_f32,
                                                  float end_point_f32);
    void     update_vehicle_current_altitude     ();
    void     set_end_point                       (float p_end_point);
    void     set_start_point                     (float p_start_point);
    void     set_action_type_A_rate              (float p_action_type_A_rate);

    float  calc_battery_consumption              ();  
    float  calc_action_type_A_time               ();  
    float  get_end_point                         ();
    float  get_start_point                       ();
    float  get_action_type_A_rate                ();
};
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Class_Action_Action_Type_B.h :

class Class_Action_Action_Type_B : public Class_Action
{
private:
    uint16_t  action_type_B_time_u16;                                                   
public:
    Class_Action_Action_Type_B                  ();
    Class_Action_Action_Type_B                  (float         p_battery_consumption_value,
                                                 uint16_t      p_action_type_B_time_u16);
    void      update_vehicle_current_altitude();
    void      set_action_type_B_time                (uint16_t  p_action_type_B_time);
    float     get_action_time                       ();
    uint16_t  get_action_type_B_time                ();
    float     calc_battery_consumption              ();   



};
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Class_Action_Action_Type_C.h :

class Class_Action_Action_Type_C : public Class_Action
{

private:
    float destination_distance_f32;
    float vehicle_speed_f32;    
public:
    Class_Action_Action_Type_C                  ();
    Class_Action_Action_Type_C                  (float battery_consumption_value_f32,
                                                 float destination_distance_f32,
                                                 float vehicle_speed_f32);
    void    update_vehicle_current_altitude     ();
    void    set_destination_distance            (float p_destination_distance);
    void    set_destination_vehicle_speed       (float p_vehicle_speed);

    float   calc_battery_consumption            ();
    float   calculate_flight_time               ();
    float   get_destination_distance            ();
    float   get_destination_vehicle_speed       ();

    
};
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Class_Action_Action_Type_D.h :

class Class_Action_Action_Type_D : public Class_Action
{
private:
    float  end_point_f32;       
    float  start_point_f32;                                
    float  action_type_D_rate_f32;         
public:
    Class_Action_Action_Type_D                   ();
    Class_Action_Action_Type_D                   (float battery_consumption_value_f32,
                                                  float action_type_D_rate_f32,
                                                  float start_point_f32,
                                                  float end_point_f32);
    void     update_vehicle_current_altitude     ();
    void     set_end_point                       (float p_end_point);
    void     set_start_point                     (float p_start_point);
    void     set_action_type_D_rate              (float p_action_type_D_rate);

    float  calc_battery_consumption            ();   
    float  calc_action_type_D_time             ();  
    float  get_end_point                       ();
    float  get_start_point                     ();
    float  get_action_type_D_rate              ();

};
-------------------------------------------------------------------------

-------------------------------------------------------------------------
Class_Move.h:

class Class_Move: public Class_Action_Action_Type_A, public Class_Action_Action_Type_B, public Class_Action_Action_Type_C, public Class_Action_Action_Type_D
{                                    
public:

    Class_Move                              ();

};
-------------------------------------------------------------------------


-------------------------------------------------------------------------
main.c:

#include <list.h>
#include "Class_Move.h"
int main()
{
    
    list<Class_Move*>           list_Moves;
    list<Class_Move*>::iterator iter_Moves;
    
    list_Moves.push_back(new Class_Action_Action_Type_A());
    list_Moves.push_back(new Class_Action_Action_Type_B());
    list_Moves.push_back(new Class_Action_Action_Type_C());
    list_Moves.push_back(new Class_Action_Action_Type_D());
}

【问题讨论】:

  • 我相信你真正想要的是直接从Class_Action继承Class_Move,然后从那里继承所有四种类型并使用多态
  • @IWonderWhatThisAPI感谢您的支持。但是,我想知道这种方式会导致某些参数的内存重复。你怎么看?

标签: c++ oop design-patterns object-oriented-analysis


【解决方案1】:

我会扭转局面。但是,首先,这些动作是针对一个班级的吗?如果它们只是动作,你为什么称它们为 Class_Action?

class Class_Action

对比

class Action

这只是一个命名的事情。无论如何,我会这样做:

class Action {
};

class Move_Action: public Action {
};

...

std::vector<Action *> vector;
-or-
std::vector<std::shared_ptr<Action>> vector;

标准多态性。

【讨论】:

  • 我认为您的意思是从Action 派生Move_Action
  • @cmannett85 你是对的。我不知道我在想什么。更新了答案。
  • @JosephLarson 感谢您的支持。如果我喜欢这个或使用 std::list list_Data ,是否可以通过从 list_Data 进行类型转换来单独达到 get_action_time() [基于动作 B 的值]。现在我只能从 list_Data 访问 get_battery_consumption_value() 、 get_battery_consumption_result() 和 get_action_time() 以及 Action 类的设置器。
  • if (typeid((*iter_All)).name() == typeid(Action_A).name()) { cout
【解决方案2】:

这里是我提到的:

    list<Action*> list_All;
    list<Action*>::iterator iter_All;
    for (iter_All = list_All.begin(); iter_All != list_All.end(); iter_All++)
    {
        if (typeid((*iter_All)).name() == typeid(Action_A).name())
        {
            cout << A << endl;
        }
        if (typeid((*iter_All)).name() == typeid(Action_B).name())
        {
            cout << B << endl;
        }
        if (typeid((*iter_All)).name() == typeid(Action_C).name())
        {
            cout << C << endl;
        }
        if (typeid((*iter_All)).name() == typeid(Action_D).name())
        {
            cout << D << endl;
        }
    }   

【讨论】:

    猜你喜欢
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 2021-12-25
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多