简体   繁体   English

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

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

I don't know how to summarize my question so couldn't find an answer on Google.我不知道如何总结我的问题,所以在谷歌上找不到答案。

When overriding a parent method,重写父方法时,

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

Works perfectly.完美运行。 But the parent method requires the information from the Child class instance to work properly, which is not given as arguments.但是父方法需要来自子 class 实例的信息才能正常工作,而不是作为 arguments 给出。 So my question is, does C++ have a mechanism to let the Parent know which instance of a Child class calls a Parent method, like without doing Parent::method(this) ?所以我的问题是,C++ 是否有一种机制让 Parent 知道 Child class 的哪个实例调用 Parent 方法,就像不做Parent::method(this)一样?

The thing that makes me think this is, if you do something like this,让我想到的是,如果你做这样的事情,

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

It gives: error: call to non-static member function without an object argument.它给出:错误:在没有 object 参数的情况下调用非静态成员 function。 So the compiler needs to know the instance, which was not also given in the child class.所以编译器需要知道实例,在子 class 中也没有给出。 But did not raise an error so it must have known the instance.但没有引发错误,因此它必须知道该实例。

Edit: I added the Qt tag because I am experimenting on a Qt class.编辑:我添加了 Qt 标签,因为我正在试验 ZE8801102A40AD89DDCFDCAEBF008D25Z class。 So that I can give an example if needed.这样我可以在需要时举一个例子。

Edit2:编辑2:

devicedialog.h设备对话框.h

class DeviceDialog : public QDialog
{
    Q_OBJECT

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

devicedialog.cpp设备对话框.cpp

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

exec() function activates and shows a QDialog on the screen. exec() function 激活并在屏幕上显示一个 QDialog。 However, that way it is called, it seems like the parent method has no way of knowing which dialog to show (no parameters passed).但是,以这种方式调用它,似乎父方法无法知道要显示哪个对话框(未传递参数)。 The only knowledge could be the identity of the instance calling it.唯一的知识可能是调用它的实例的身份。 I am just asking if this knowledge transferred to the method in the background.我只是问这些知识是否转移到后台的方法中。

This is nothing special to member functions of a parent class.这对于父 class 的成员函数没有什么特别之处。 Calling a function of the child class via explicitly naming the type:通过显式命名类型来调用子 class 的 function:

Child::method();

works in exactly the same way in this regard.在这方面的工作方式完全相同。 Used outside of a member functions definition it causes the same error.在成员函数定义之外使用它会导致相同的错误。

The relevant paragraph of the standard is §9.3.1:该标准的相关段落是§9.3.1:

When an id-expression that is not part of a class member access syntax and not used to form a pointer to member is used in a member of class X in a context where this can be used, if name lookup resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression using (*this) as the postfix-expression to the left of the.如果在可以使用此的上下文中,如果名称查找解析了 id -expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression using (*this) 作为左边的后缀表达式。 operator.操作员。

So, in other words, the call所以,换句话说,调用

Parent::method();

inside a member function is transformed into something akin to在成员 function 内部被转换为类似于

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

I think you are just being confused by the language's attempt to make things easier on you.我认为你只是对语言试图让你更轻松的尝试感到困惑。 Your example function is equivalent to您的示例 function 相当于

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

Just as you cannot call a (non-static) method in the child class without an object, you cannot call the parent's method without an object.正如你不能在没有 object 的情况下调用子 class 中的(非静态)方法一样,你不能在没有 object 的情况下调用父级的方法。 However, the context is the body of such a method.但是,上下文是这种方法的主体。 Within the body, the context is assumed to be *this .在正文中,上下文假定为*this Just as you can refer to data members without explicitly prefixing " this-> ", you can call methods without the prefix.就像你可以在没有显式前缀“ this-> ”的情况下引用数据成员一样,你可以调用没有前缀的方法。

This is still a c++ specific question.这仍然是 c++ 的具体问题。 Qt just utilizes it. Qt 只是利用它。 You need to study objects, inheritance, and virtual methods.您需要研究对象、inheritance 和虚拟方法。

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

The above works because the child has access to the parents methods (that are not private).上述工作是因为孩子可以访问父母的方法(不是私有的)。 Because the method is an override of the parents virtual method, the only way for the compiler to know you want to call the parents method is to call it with scope resolution '::' in the child.因为该方法是对父虚拟方法的覆盖,所以编译器知道您要调用父方法的唯一方法是在子中使用 scope 分辨率“::”来调用它。

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

The above does not work because there is no instantiated object.由于没有实例化的object,上述不起作用。 When you call a method, you call it on the object (unless it is a static method).当你调用一个方法时,你在 object 上调用它(除非它是一个 static 方法)。 So instead you would do something like:所以你会做类似的事情:

int main() {
  SomeParentClass parent;
  parent.someMethod();

  ChildClass child;
  child.someMethod(); // accesses the childs overridden method and not the parents.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM