对象切片

上代码

 1 class UIControlBase  : public QObject
 2 {
 3     Q_OBJECT
 4 
 5 public:
 6     UIControlBase(const UIControlBase&);
 7     UIControlBase(QObject *parent);
 8     UIControlBase();
 9     ~UIControlBase();
10 };class ComboxUIControl  : public UIControlBase
11 {
12     Q_OBJECT
13 
14 public:
15     ComboxUIControl(QObject *parent);
16     ComboxUIControl();
17     ~ComboxUIControl();
18     void SetItems(QStringList qStringList);
19     QStringList qStringList;
20 };  
21 //调用
22 QList<UIControlBase> List_Item1;
23  ComboxUIControl ComboxUIControl_Temp1;
24  ComboxUIControl_Temp1.qStringList.append("122");
25  List_Item1.append(ComboxUIControl_Temp1);
26 
27  UIControlBase fu = List_Item1[0];
28  ComboxUIControl* comboBox = dynamic_cast<ComboxUIControl*>(&fu);
29  ComboxUIControl* comboBox1 = static_cast<ComboxUIControl*>(&fu);
//qStringList显示不出来值
这里存在几个问题:
    1. QList<UIControlBase>存储的是UIControlBase对象,当我们添加ComboxUIControl_Temp1时,会发生对象切片。
      也就是说,只有基类部分被复制到列表中,而派生类特有的部分(如qStringList)会被丢弃。
    2. 因此,当我们从List_Item1中取出元素时,它已经是一个纯粹的UIControlBase对象,不再具有ComboxUIControl的特性。
    3. 所以,无论使用dynamic_cast还是static_cast,都无法将一个基类对象转换为派生类对象,因为派生类对象的数据已经丢失。
    4. dynamic_cast会失败,返回nullptr;而static_cast则是危险的,因为它强制转换,但实际对象并不是派生类对象,访问其派生类成员是未定义行为。
    5. 解决方案:
        1. 如果我们想要在容器中存储多态对象,应该存储指针(最好是智能指针),而不是对象本身。例如,我们可以存储指向UIControlBase的指针:
        2. 使用QList<UIControlBase*>,然后添加派生类对象的指针。但是需要注意,当我们存储指针时,需要管理内存,确保在适当的时候释放。
        3. 另外,为了支持多态,基类通常需要至少一个虚函数(析构函数通常是虚函数)。
        4. 方案1:使用指针(推荐)

        5.  1 // 存储指针而不是对象
           2 QList<UIControlBase*> List_Item1;
           3 
           4 ComboxUIControl* comboBox = new ComboxUIControl();
           5 comboBox->qStringList.append("122");
           6 List_Item1.append(comboBox);  // 存储指针
           7 
           8 // 取出时仍然是派生类对象
           9 ComboxUIControl* retrieved = dynamic_cast<ComboxUIControl*>(List_Item1[0]);
          10 if (retrieved) {
          11     qDebug() << retrieved->qStringList;  // 可以显示值
          12 }

          方案2:使用智能指针(更安全)

        6.  1 #include <QSharedPointer>
           2 
           3 QList<QSharedPointer<UIControlBase>> List_Item1;
           4 
           5 QSharedPointer<ComboxUIControl> comboBox(new ComboxUIControl());
           6 comboBox->qStringList.append("122");
           7 List_Item1.append(comboBox);
           8 
           9 // 取出时使用dynamic_pointer_cast
          10 QSharedPointer<ComboxUIControl> retrieved = 
          11     qSharedPointerDynamicCast<ComboxUIControl>(List_Item1[0]);
          12 if (retrieved) {
          13     qDebug() << retrieved->qStringList;
          14 }

           

方案1:使用指针(推荐)

posted @ 2025-12-03 09:02  家煜宝宝  阅读(3)  评论(0)    收藏  举报