我有一个班级
class BTree {
public:
int val;
BTree *next;
BTree *child;
BTree* putVal(int v) {
BTree *temp = new BTree;
temp->val = v;
return temp;
}
}*root;
可以用作吗?
root = root->putVal(12);
printf("%x %d\n",root,root->val);
在putVal调用之前打印的root = 0以及调用之后的一些内存位置。 它可能是非常糟糕的代码,但我只是想知道它是否允许并且将按预期工作?
如何调用函数?
从调用语法看来,每个变量都有一个指向类中函数的指针的副本。在这种情况下,由于尚未为对象分配内存,因此不应该工作。
答案 0 :(得分:1)
不,不允许。不允许使用空指针,并且"调用成员函数"算作用。
使用空指针可以做一些事情并不算作使用。将它们与其他指针进行比较,并分配新值是两种最常见的指标。
根本原因是空指针不指向对象,并且调用对象的成员函数确实需要实际对象。
答案 1 :(得分:1)
你有什么是未定义的行为 - 使用NULL对象指针调用方法是UB。但是,要回答您的问题,为什么它在您的情况下完全有效 - 在大多数编译器中,只有虚函数地址存储在对象中。非虚函数(例如putVal
)的调用方式与全局函数类似,只是它们具有指向对象的其他隐藏参数。
在实践中,这意味着如果在许多情况下如果使用NULL指针调用虚函数,它将立即崩溃。如果您调用非虚函数,那么当第一次在函数体中访问对象时,它将崩溃(访问意味着 - 读取或写入字段,或调用虚函数)。由于您的函数根本不访问您的对象,因此不会崩溃。
同样,你拥有的是UB,不应该使用这样的代码。即使使用上面描述的实现细节(可能是也可能不是),您不希望将函数设置为虚拟,或者更新编译器并获得令人惊讶的崩溃。但是我觉得理解C ++中通常的方法调用实现方式是值得的。
答案 2 :(得分:0)
正如其他同行所提到的,空指针不是一个对象,并且尝试访问成员函数会导致崩溃,但PutVal函数具有成为静态函数的属性。
PutVal接受一个int并从参数中创建一个对象。 putVal不对对象进行操作而是初始化它。
使putVal静态以实现更好的实现。