假设下面是 C++。在调用 a->method1()
之前,它有一个
assert (a)
来检查 a
是否正常。
调用a->method2()
没有这样的断言;而是 method2
本身
通过 assert (this)
检查有效的 this
。
它是可行的代码。 C++ 规范?
即使它被标准所涵盖,它当然也不是很好的风格,而且 如果代码发生更改,则容易出错,例如如果方法是 重构为虚拟方法。我只是好奇什么 标准不得不说,无论 g++ 代码是设计还是仅仅 意外。
下面的代码在 g++ 中按预期工作,即在
method2
按预期触发,因为只是调用 method2
没有
this
指针是必需的。
#include <iostream>
#include <cassert>
struct A
{
int a;
A (int a) : a(a) {}
void method1 ()
{
std::cout << a << std::endl;
}
void method2 ()
{
assert (this);
std::cout << a << std::endl;
}
};
void func1 (A *a)
{
assert (a);
a->method1();
}
void func2 (A *a)
{
a->method2();
}
int main ()
{
func1 (new A (1));
func2 (new A (2));
func2 (nullptr);
}
输出
1
2
Assertion failed: this, file main.cpp, line 16
最佳答案
Even if it's [permitted] by the standard
不是。
it not good style of course
没有。
and it's error prone if the code ever changes, e.g. if the method is refactored to a virtual method.
我承认虚成员函数更有可能在这里导致“崩溃”,但您已经有未定义的行为,这不仅仅是理论上的问题:您可以期待诸如断言或要省略的条件,或发生其他奇怪的事情。
这种模式是一个很大的禁忌。
I am just curios about what the standard has to say
上面写着:
[expr.ref/2]
[..] For the second option (arrow) the first expression shall be a prvalue having pointer type. The expressionE1->E2
is converted to the equivalent form(*(E1)).E2
[..]
[expr.unary.op/1]
The unary*
operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. [..]
请注意,它并没有明确地说“对象必须存在”,但通过说表达式引用对象,它隐含地告诉我们必须存在一个对象。这种“差距”在设计上直接属于未定义行为的定义。
whether g++ code words by design or just by accident.
最后一个。
关于c++ - "assert (this)"是可行的模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61697977/