if (!this) { 返回 false; }

发布于 2024-07-15 12:20:26 字数 366 浏览 4 评论 0原文

我偶然发现了这段代码,在我看来它完全被破坏了,但它确实发生了 thisnull。 我只是不明白这怎么可能是 null

它是在正常的方法调用中,例如

myObject->func();

MyObject::func() 中,我有

if (!this) { return false; }

什么办法可以拥有第一行抛出 NullPointerException 而不是进入 null(?) 方法?

I stumbled upon this piece of code which seems totaly broken to me, but it does happen that this is null. I just don't get how this can be null

it is inside a normal method call such as

myObject->func();

inside MyObject::func() we have

if (!this) { return false; }

is there any way I can have the first line to throw a NullPointerException instead of going inside the null(?) method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

淡紫姑娘! 2024-07-22 12:20:26

如果您有:

MyObject *o = NULL;

o->func();

接下来会发生什么取决于 func 是否是虚拟的。 如果是,那么它将崩溃,因为它需要一个对象来从中获取 vtable。 但如果它不是虚拟的,则调用将继续,并将 this 指针设置为 NULL。

我相信标准说这是“未定义的行为”,所以任何事情都可能发生,但典型的编译器只是生成代码而不检查指针是否为 NULL。 一些著名的库依赖于我所描述的行为:MFC 有一个名为 SafeGetHandle 之类的函数,可以在空指针上调用该函数,并在这种情况下返回 NULL。

您可能想要编写一个可重用的辅助函数:

void CheckNotNull(void *p)
{
    if (p == NULL)
        throw NullPointerException();
}

然后您可以在函数的开头使用它来检查其所有参数,包括 this

CheckNotNull(this);

If you have:

MyObject *o = NULL;

o->func();

What happens next depends on whether func is virtual. If it is, then it will crash, because it needs an object to get the vtable from. But if it's not virtual the call proceeds with the this pointer set to NULL.

I believe the standard says this is "undefined behaviour", so anything could happen, but typical compilers just generate the code to not check whether the pointer is NULL. Some well known libraries rely on the behaviour I described: MFC has a function called something like SafeGetHandle that can be called on a null pointer, and returns NULL in that case.

You might want to write a reusable helper function:

void CheckNotNull(void *p)
{
    if (p == NULL)
        throw NullPointerException();
}

You can then use that at the start of a function to check all its arguments, including this:

CheckNotNull(this);
不甘平庸 2024-07-22 12:20:26

捕获此类错误(根据设计)的一种方法是使用指针包装类(类似于 shared_ptr),该类在创建时会抛出空指针参数。 当取消引用时它也可能抛出,但这有点晚了 - 我想总比没有好。

A way to trap these kind of errors (by design) is using a pointer-wrapper class (resembling a shared_ptr) that throws upon creation with a null pointer argument. It may throw also when dereferenced, but that's a little late - better than nothing, I guess.

z祗昰~ 2024-07-22 12:20:26
if(this == null)
   throw new NullPointerException;
if(!this)
   return false;
if(this == null)
   throw new NullPointerException;
if(!this)
   return false;
你怎么这么可爱啊 2024-07-22 12:20:26

(this == NULL) 根据标准是未定义的行为。 我认为您应该删除此检查:)

假设我们进行以下调用:

((CSomeClass*) 0)->method();

行为已经未定义,那么为什么还要在 CSomeClass::method 中检查 this == NULL 呢?

编辑:
我假设如果您不使用成员变量,您的编译器将处理 (0 == this),但它会在哪里找到虚拟表指针? 在这种情况下,您的类不能使用多态性。

(this == NULL) is undefined behaviour according to the standard. I think you should remove this check :)

Assume we make the following call:

((CSomeClass*) 0)->method();

The behaviour is already undefined, so why bother doing the check for this == NULL in CSomeClass::method ?

EDITED:
I Assume that your compiler will handle (0 == this) if you don't use member variables, but where would it find the virtual table pointer? In this case, your class can not use polymoprhism.

Saygoodbye 2024-07-22 12:20:26

this 可能为 null。 我怀疑这段代码正在尝试(严重地)检测竞争条件,其中对象尚未完成初始化或已被删除。

It's possible for this to be null. I suspect that this code is trying to (badly) detect a race condition, where the object is not yet finished being initialized, or has been deleted.

够运 2024-07-22 12:20:26

在这样的情况下,该指针可能会变为空:

class Test
{

public:
    bool f();

private:
    int m_i;
};


bool Test::f()
{
    if(!this)
    {
        return false;
    }

    m_i = 0;
    return true;

}


int main(int argc, char **argv)
{
    Test* p = new Test;
    delete p;
    p = NULL;

    p->f();
}

我猜有人做了一个快速破解以避免访问冲突异常。

this pointer can become null in cases like these:

class Test
{

public:
    bool f();

private:
    int m_i;
};


bool Test::f()
{
    if(!this)
    {
        return false;
    }

    m_i = 0;
    return true;

}


int main(int argc, char **argv)
{
    Test* p = new Test;
    delete p;
    p = NULL;

    p->f();
}

I guess somebody did a quick hack to avoid to the access violation exception.

你怎么敢 2024-07-22 12:20:26

仅当您在已删除的对象上调用方法,或者某些内容正在写入不应写入的内存(特别是覆盖对象的 this 指针)时,才应发生 this == null 。

您应该调查您的代码到底出了什么问题,而不是尝试像这样解决它。

this == null should only occur if you are calling a method on a deleted object, or if something is writing to memory that it should not (and overwriting the object's this pointer in particular).

You should investigate what is really wrong with your code rather than trying to work around it like this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文