在指向父对象的指针上初始化子对象

时间:2013-10-30 12:34:58

标签: c++ qt pointers polymorphism

静止的动机

我正在阅读Model-View (paragraph Using a model)的教程,在Qt中使用模型。 该示例显示以下代码:

//Header file
class StringListModel : public QAbstractListModel

//main.cpp
QAbstractItemModel *model = new StringListModel(numbers);

以下解释。

  

请注意,StringListModel声明为QAbstractItemModel。这允许我们使用模型的抽象接口,并确保代码仍然有效,即使我们用不同的模型替换字符串列表模型。

我这样解释了他们的答案:

您可以在model上开发项目,如果您需要更改基础数据结构,您可以这样做:

//Header file
class NewStringListModel : public QAbstractListModel

//main.cpp
//QAbstractItemModel *model = new StringListModel(numbers);  Stoped using this, old
QAbstractItemModel *model = new NewStringListModel(numbers);  //complete model change with just a single line

广义

  • 这被视为指针演员吗?

  • 如果子类实现了基类中不存在的方法,那会造成问题吗?

这将是:

pointerToParent->childMethodNotExistingInParent()
  • 这是一种不好的做法吗?如果没有,为什么不呢?

2 个答案:

答案 0 :(得分:1)

Is this considered a pointer cast?:是的,指向NewStringListModel的指针已投放到基类QAbstractItemModel

If the child class implements methods which don't exist in the base class, would that pose a problem?:没问题,通常需要实现在基类中不存在的额外代码,但是只有将指针保存到子类而不是基类时才能使用它class(或者在基类中实现虚函数)

Is this a bad practice? If not, why not?将无法编译,因为pointerToParent的类型为QAbstractListModel,因此NewStringListModel内的任何实现都无法访问。您需要使用static_cast或dynamic_cast才能访问cild类型:

static_cast<NewStringListModel*>(pointerToParent)->YourMethod() - 此检查在编译时键入类型,但如果您不完全确定pointerToParent类型为NewStringListModel

,则使用它是不安全的

dynamic_cast<NewStringListModel*>(pointerToParent)是最安全的方法,但您需要使用RTTI,它是一个编译器siwtch。这在运行时天气检查演员实际上可能发生。如果不是它可以抛出异常(我不确定这个细节)

勒兹。

答案 1 :(得分:1)

  • 是的,它是一个隐式的上传(即上传继承层次结构,从子到父)。这与显式转换不同,您可以在其中指定您期望的输出类型;它也不同于一个向下转换,在那里你沿着继承层次结构,从父母到孩子。

  • 是的,子类中的新方法/成员有点问题。它们不能通过父类指针直接访问。但是,您可以使用dynamic_cast<>()尝试将父指针转换为您期望的任何子类,并以这种方式访问​​新功能。虽然这不是一个理想的方法。你最好重构父/子类并使用virtual函数来避免这种情况。

  • 通常,存储和使用父类指针并不是一种不好的做法。实际上,如果您的类层次结构实现了'is-a'关系,那么它通常被认为是一种很好的做法,因为它保持了接口和实现之间的区别(理想情况下不应该影响另一个的设计)。 然而,尝试通过(适当投射的)父指针访问仅限子功能是一个可疑的领域,因为它打破了接口实现的区别。但在极少数情况下这是必要的。