什么时候可以安全地调用此->在构造函数和析构函数中 [英] When is it safe to call this-> in constructor and destructor

查看:78
本文介绍了什么时候可以安全地调用此->在构造函数和析构函数中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我还没有找到最终的答案。什么时候从对象内调用 this-> 是安全的。

I've not been able to find a conclusive answer to this so far. When is it safe to call this-> from within an object. And in particular from inside the constructor and destructor.

还有,当使用公共继承时。在此调用的结果上使用上下转换是否安全?

And also, when using public inheritance. Is it safe to use up and downcasting on the result of the this call?

因此,例如:

class foo
{
   foo():
   a(),
   b(this->a)//case 1
   {
       this-> a = 5; //case 2
   }

   int a;
   int b;
};

class bar: public baz
{
   bar():
   baz(this)//case 3 - assuming baz has a valid constructor
   {


   }

}

最后是最不可能的一个

foo()
   {
      if(static_cast<bar*>(this));//case 4
   }

以下哪种情况?合法吗?

Which of the above cases are legal?

注意:我知道上述许多做法都不可取。

Note: I'm aware a lot of the practices above are inadvisable.

推荐答案

在任何非静态成员函数中, this 指向调用函数的对象。只要是有效对象,就可以安全使用。

Within any non-static member function, this points to the object that the function was called on. It's safe to use as long as that's a valid object.

在构造函数或析构函数的体内,当前正在构造的类的有效对象。但是,如果这是某个派生类的基础子对象,则此时只有基础子对象有效;因此通常不安全地向下转换并尝试访问派生类的成员。出于同样的原因,您需要在这里小心地调用虚函数,因为虚函数是根据创建或销毁的类而不是最终的替代程序进行调度的。

Within the body of a constructor or destructor, there is a valid object of the class currently being constructed. However, if this is the base sub-object of some derived class, then only the base sub-object is valid at that time; so it's generally not safe to down-cast and try to access members of the derived class. For the same reason, you need to be careful calling virtual functions here, since they are dispatched according to the class being created or destroyed, not the final overrider.

构造函数的初始值设定项列表,您只需要小心访问已初始化的成员即可;

Within the initialiser list of a constructor, you'll need to be careful only to access members that have been initialised; that is, members declared before the one currently being initialised.

因为基本子对象总是首先被初始化,所以向上转换到基类总是安全的。

Up-casting to a base class is always safe, since base sub-objects are always initialised first.

对于您刚刚添加到问题中的特定示例:

For the specific examples you just added to the question:


  • 情况1很好(如果是脆弱的话),因为 a 当时已被初始化。用 b 的值初始化 a 将会是不确定的,因为 b a 之后初始化。

  • 情况2很好:所有成员均已在该点初始化。

  • 情况3无法编译,因为没有合适的 foo 构造函数。如果有的话,则取决于构造函数的作用-在初始化成员之前是否尝试访问成员。

  • 第4种情况将是格式正确的缺少的,但如果尝试使用指针访问对象,则很危险。 尚未指向有效的 bar 对象(仅 foo 部分已经初始化),因此访问 bar 的成员可能会给出不确定的行为。只需检查指针是否为非null即可,并且始终会给出 true (无论是否应用无意义的强制转换)。

  • case 1 is fine (if fragile), since a has been initialised at that point. Initialising a with the value of b would be undefined, since b is initialised after a.
  • case 2 is fine: all members have been initialised at that point.
  • case 3 won't compile, since there's no suitable foo constructor. If there were, then it would depend on what that constructor did with it - whether or not it tried to access members before they were initialised.
  • case 4 would be well-formed if you added the missing ), but dangerous if you tried to use the pointer to access the object. this does not yet point to a valid bar object (only the foo part has been initialised) so accessing members of bar could give undefined behaviour. Simply checking whether the pointer is non-null is fine, and will always give true (whether or not you apply a pointless cast).

这篇关于什么时候可以安全地调用此-&gt;在构造函数和析构函数中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆