C++ 通过指针调用函数而不从对象分配内存

C++ 通过指针调用函数而不从对象分配内存,c++,class,pointers,member-functions,C++,Class,Pointers,Member Functions,我有一门课 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("

我有一门课

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,在调用之后打印一些内存位置。 这可能是非常糟糕的代码,但我只想知道它是允许的,并将按预期工作

函数是如何调用的


从调用语法来看,似乎每个变量都有一个指向类中函数的指针副本。在这种情况下,这不应该起作用,因为内存尚未分配给对象

不,这是不允许的。不允许使用空指针,“调用成员函数”也算作使用

有几件事你可以用空指针做,它们不算是有用的。将它们与其他指针进行比较,并分配新值是两种最常见的方法


根本原因是空指针不指向对象,调用对象的成员函数需要实际对象

您拥有的是未定义的行为-使用空对象指针调用方法是UB。然而,为了回答您的问题,为什么它在您的情况下会工作——在大多数编译器中,对象中只存储虚拟函数地址。非虚函数(如
putVal
)的调用方式与全局函数类似,只是它们具有指向对象的附加隐藏参数

实际上,这意味着在许多情况下,如果使用空指针调用虚拟函数,它将立即崩溃。如果您调用非虚拟函数,那么当第一次在函数体中访问对象时,它将崩溃(访问的意思是读取或写入字段,或者调用虚拟函数)。由于函数根本不访问对象,因此不会发生崩溃


同样,您拥有的是UB,这样的代码永远不应该被使用。即使有了上面描述的实现细节(这可能是真的,也可能不是真的),您也不希望使函数成为虚拟函数,或者更新编译器,从而导致意外的崩溃。但我认为理解C++中方法调用的一般实现方式是值得的。

< P>其他的同行已经提到空指针不是对象,试图访问成员函数会导致崩溃,但是PtVaLL函数的属性变成静态函数。p> PutVal接受一个int并从参数生成一个对象。putVal不对对象执行操作,而是对其进行初始化

将putVal设置为静态,以便更好地实现