假设下面的C ++。在调用a->method1()
之前,它有一个
assert (a)
检查a
是否健全。
呼叫a->method2()
没有这样的断言;代替method2
本身
通过this
检查有效的assert (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
答案 0 :(得分:2)
'not a C'.__init__
不能为this
,(否则已经存在未定义的行为)。
以您的情况
nullptr
调用未定义的行为,因此事后检查毫无用处。
更好的签名意味着不是空指针是引用:
a->method2(); // with a == nullptr
答案 1 :(得分:2)
预先回答您的问题:“ C ++:“断言(此)”是可行的模式吗?” -否。
requests.exceptions.ConnectionError: ('Connection aborted.', PermissionError(13, 'Permission denied'))
是毫无意义。 C ++标准保证assert(this);
指针在有效程序中从不 this
。
如果您的程序有undefined behaviour,那么所有赌注当然都是无效的,nullptr
可能是this
。但是在这种情况下,断言不是正确的解决方案,而修复UB是正确的。
答案 2 :(得分:2)
即使它是[允许]标准
不是。
当然不是很好的风格
不。
,如果代码更改,则容易出错,例如方法是否重构为虚拟方法。
我承认,虚拟成员函数很可能在此处导致“崩溃”,但是您已经具有未定义的行为,而不仅仅是理论上的担忧:您可以期望诸如断言或消除条件或发生其他奇怪的事情。
这种模式是很大的禁忌。
我只是对标准要说的东西感到好奇
它说:
[expr.ref/2]
[..] 对于第二个选项(箭头),第一个表达式应该是具有指针类型的 prvalue 。表达式E1->E2
转换为等效形式(*(E1)).E2
[..]
[expr.unary.op/1]
一元*
运算符执行间接操作:应用该表达式的表达式应为指向对象类型的指针或为函数类型的指针,并且结果为左值引用表达式所指向的对象或函数。 [..]
请注意,它没有明确地说“对象必须存在”,但是通过说表达式是指对象,它隐式告诉我们必须成为。通过设计,这种“间隙”直接属于未定义行为的定义。
g ++代码是故意设计的还是偶然的。
最后一个。