1

提问的动机

我正在阅读有关 模型视图的教程(使用模型的段落)在 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()
  • 这是一个不好的做法吗?如果不是,为什么不呢?
4

2 回答 2

1
  • 是的,它是一种隐式向上转型(即沿继承层次结构向上,从子级到父级)。这与显式转换不同,在显式转换中,您可以准确指定您期望的输出类型;它也与向下转换不同,向下转换是沿着继承层次结构,从父级到子级。

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

  • 一般来说,存储和使用父类指针不是坏习惯。事实上,如果您的类层次结构实现“is-a”关系,通常被认为是一种好的做法,因为它保持了接口和实现之间的区别(理想情况下,一个不应影响另一个的设计)。但是,尝试通过(适当转换的)父指针访问子功能是可疑的领域,因为它打破了接口实现的区别。但在极少数情况下这是必要的。

于 2013-10-30T12:55:24.403 回答
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?:没问题,通常需要实现基类中不存在的额外代码,但是只有在保持指向子类而不是基类的指针(或者您在内部实现虚函数)时才能使用它基类)

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。这会在运行时检查演员是否实际发生。如果不是,它会抛出异常(我不确定这个的细节)

拉兹万。

于 2013-10-30T12:49:28.557 回答