C++如何知道子类调用父方法?

How does C++ knows child class calls a parent method?

本文关键字:方法 调用 子类 何知道 C++      更新时间:2023-10-16

我不知道如何总结我的问题,所以在谷歌上找不到答案。

重写父方法时,

void Child::method(){
//stuff
Parent::method();
}

完美工作。但是父方法需要来自 Child 类实例的信息才能正常工作,这些信息不作为参数给出。所以我的问题是,C++是否有一种机制可以让 Parent 知道 Child 类的哪个实例调用 Parent 方法,就像Parent::method(this)一样?

让我觉得这一点的是,如果你做这样的事情,

int main(){
SomeParentClass::someMethod();
}

它给出:错误:调用没有对象参数的非静态成员函数。因此,编译器需要知道实例,子类中也没有给出该实例。但是没有引发错误,因此它必须知道该实例。

编辑:我添加了Qt标签,因为我正在尝试Qt类。以便如果需要,我可以举个例子。

编辑2:

设备对话框.h

class DeviceDialog : public QDialog
{
Q_OBJECT
public:
explicit DeviceDialog(QWidget *parent = nullptr);
int exec() override;
~DeviceDialog() override;
}

设备对话框.cpp

int DeviceDialog::exec(){
// My code.
return QDialog::exec();
}

exec()功能激活并在屏幕上显示QDialog。但是,以这种方式调用它,似乎父方法无法知道要显示哪个对话框(未传递参数(。唯一的知识可能是调用它的实例的身份。我只是问这些知识是否转移到后台的方法中。

我认为你只是对语言试图让你更轻松感到困惑。您的示例函数等效于

void Child::method(){
//stuff
this->Parent::method();
}

正如不能在没有对象的情况下调用子类中的(非静态(方法一样,也不能在没有对象的情况下调用父类的方法。但是,上下文是此方法的主体。在正文中,假定上下文是*this。正如您可以在不显式前缀"this->"的情况下引用数据成员一样,您可以调用不带前缀的方法。

这对于父类的成员函数来说没有什么特别之处。 通过显式命名类型来调用子类的函数:

Child::method();

在这方面以完全相同的方式工作。在成员函数定义之外使用会导致相同的错误。

该标准的相关段落是§9.3.1:

当不属于类成员的 id 表达式访问语法时 并且不用于形成指向成员的指针 在类的成员中使用 X 在可以使用此功能的上下文中,如果名称查找解析了 名称在 id 表达式中为某些非静态非类型成员 类 C,以及如果 id 表达式可能被计算或 C 是 X 或 X 的基类,id 表达式转换为 使用 (*this( 作为后缀表达式的类成员访问表达式 在 的左侧。算子。

所以,换句话说,电话

Parent::method();

在成员函数内部转换为类似于

(*this).Parent::method();

这仍然是一个特定于 c++ 的问题。Qt只是利用它。您需要研究对象、继承和虚拟方法。

void Child::method() {
Parent::method();
// this->Parent::method();
}

上述方法之所以有效,是因为孩子可以访问父方法(非私有方法(。由于该方法是父虚拟方法的重写,因此编译器知道您要调用父方法的唯一方法是在子方法中使用范围解析"::"调用它。

int main() {
SomeParentClass::someMethod();
}

上述方法不起作用,因为没有实例化的对象。调用方法时,将在对象上调用它(除非它是静态方法(。因此,您可以执行以下操作:

int main() {
SomeParentClass parent;
parent.someMethod();
ChildClass child;
child.someMethod(); // accesses the childs overridden method and not the parents.
}