C++ 子类化、继承和强制转换

Posted

技术标签:

【中文标题】C++ 子类化、继承和强制转换【英文标题】:C++ Subclassing, Inheritance and Casting 【发布时间】:2011-02-09 06:20:06 【问题描述】:

这个具体的难题我很难解释,所以我会尽力而为。

在Qt框架中,有2个类:QTreeWidget和QTreeWidgetitem。

我对 QTreeWidgetitem 进行了子类化:


class MyQTreeWidgetitem : public QObject, public QTreeWidgetitem


...

public:
  int myCustomVariable;

我将它添加到 QTreeWidget 做类似的事情:


MyQTreeWidgetitem *item = new MyQTreeWidgetitem;
item->myCustomVariable = 10;

tree->addTopLevelItem(item);

现在,如果我需要调用 tree->topLevelItem(x),我得到的只是 QTreeWidgetitem*。

但是,我所追求的是 MyQTreeWidgetitem* 所以我:


MyQTreeWidgetItem *theitem = (MyQTreeWidgetItem*)tree->topLevelItem(n);

问题在于 theitem->myCustomVariable 不再等于 10。

有没有办法让 MyQTreeWidgetitem 保持完整?

【问题讨论】:

您确定tree->topLevelItem(n); 是您添加的原始对象吗? 是的.. 而 templatetypedef 的回答让我进一步挖掘。 dynamic_cast 确实有效(!= 0)。在我的班级进一步调查后,数据(和其他所有内容)确实保持不变。我希望我可以删除这个问题。 @ShiGon- 功劳属于托尼,而不是我。我只是对他的答案进行了轻微的格式清理,使其看起来更闪亮。 :-) 你仍然应该接受这个答案,因为它确实帮助你解决了问题。 嗯,这很令人困惑.. Tony 回答了但 templatetypedef 已编辑? 【参考方案1】:

我不知道Qq,但是你可以尝试做一个正确的dynamic_cast<>来验证对象是否真的是MyQTreeWidgetItem*(否则返回0),以及正确执行指针转换(我是不确定 C 样式转换是否返回 QObject 的地址)。您也可以打印出指针并更深入地了解这个问题。

【讨论】:

感谢您的回答。查看我的子类内部的数据后,我可以看到数据仍然存在。毕竟问题不在于选角。【参考方案2】:

在 C++ 程序中使用 C 风格的转换通常是个坏主意。可以将它用于原始类型,但应避免用于类。虽然在这种特殊情况下可能没问题,但有一天你会发现自己因此而陷入困境。

使用dynamic_cast<> 可能没问题。由于您不使用虚拟继承,因此您可能希望也使用static_cast<>,它的优点是不需要RTTI(某些平台可能对它的支持较差)并且速度稍快。我还听说 dynamic_cast 有时无法跨共享库边界正常工作。

对于 QObject 子类之间的向下转换,Qt 中还提供了qobject_cast<>。在这种情况下它不会帮助您,因为 QTreeWidgetItem 不是 QObject 子类,但可能会在您需要从 QObject* 转换为 MyQTreeWidgetItem* 的其他地方帮助您。如果您使用 Qt 插件机制,它也用于转换为接口。

【讨论】:

以上是关于C++ 子类化、继承和强制转换的主要内容,如果未能解决你的问题,请参考以下文章

java 里 可以把一个父类强制转换成一个子类 不能把一个子类强制转换成一个父类? 对吗?

C++ 继承和强制转换

java父类强制转换成子类的问题

java中怎样做可以把父类强制转换成子类

java中强制类型转换

java中怎样做可以把父类强制转换成子类