对象切片
上代码
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显示不出来值
- QList<UIControlBase>存储的是UIControlBase对象,当我们添加ComboxUIControl_Temp1时,会发生对象切片。
也就是说,只有基类部分被复制到列表中,而派生类特有的部分(如qStringList)会被丢弃。 - 因此,当我们从List_Item1中取出元素时,它已经是一个纯粹的UIControlBase对象,不再具有ComboxUIControl的特性。
- 所以,无论使用dynamic_cast还是static_cast,都无法将一个基类对象转换为派生类对象,因为派生类对象的数据已经丢失。
- dynamic_cast会失败,返回nullptr;而static_cast则是危险的,因为它强制转换,但实际对象并不是派生类对象,访问其派生类成员是未定义行为。
- 解决方案:
- 如果我们想要在容器中存储多态对象,应该存储指针(最好是智能指针),而不是对象本身。例如,我们可以存储指向UIControlBase的指针:
- 使用QList<UIControlBase*>,然后添加派生类对象的指针。但是需要注意,当我们存储指针时,需要管理内存,确保在适当的时候释放。
- 另外,为了支持多态,基类通常需要至少一个虚函数(析构函数通常是虚函数)。
-
方案1:使用指针(推荐)
-
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:使用智能指针(更安全)
-
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 }

浙公网安备 33010602011771号