类变量不保留C++值

C++ class variable does not retain values

本文关键字:C++ 保留 类变量      更新时间:2023-10-16

我最近开始用C++编程(用Java做过)。我遇到类变量不保留其值的问题。

bt_builder.h

class BtreeBuilder{
  BtreeNode *root;   //will point to root of the tree
  public:Status insertBuilderKey(KeyId);
.....
}

bt_builder.cpp

Status BtreeBuilder::insertBuilderKey(KeyId k){
  ....
  BtreeIndex newroot ;
  newroot.insertKey(Ld.getKey(0),0,left,right);
  root = &newroot;
  printnode(root);// prints correct values
  ....
}

bt_main.cpp

int main()
{
  BtreeBuilder *btb = new BtreeBuilder();
  btb->insertBuilderKey(1);//inside this method it has printed values corretly
  btb->printroot();//now it is printing garbage values for root node it seems that the value which  was set for root inside the method is no longer there
}

所以我的问题是为什么它不保留方法之外的root值,即使它是一个类变量?

这个问题的解决方案是什么。

BtreeIndex newroot ; 在堆栈上创建了一个BtreeIndex BtreeBuilder::insertBuilderKey,但是一旦方法完成,保存该变量的堆栈帧就会被销毁,因此您的变量也会被销毁。

您需要在堆上创建BtreeIndexBtreeIndex* newroot = new BtreeIndex();

有关详细信息,请参阅 http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/。

你有类成员BtreeNode root;,你从堆栈上的变量中为其赋值:BtreeIndex newroot 。当代码退出作用域(退出函数insertBuilderKey(KeyId k){...}时,此变量将被销毁。如果需要分配新的根,请在堆BtreeIndex newroot = new BtreeIndex()中创建它并继续。不要忘记删除之后需要的内容。

默认情况下,

局部变量是自动存储持续时间的,并且在退出作用域时(例如从函数返回)时不复存在。

因此,保留其地址(在指针中)会导致悬空指针 - 指向不再存在的内容的指针。 取消引用该指针会导致未定义的行为。

这与Java完全不同,Java依赖于垃圾检测器检测何时不再引用对象并销毁它 - 只要存在对它的引用,就可以使用它。

当您尝试插入树时:

Status BtreeBuilder::insertBuilderKey(KeyId k){
....
BtreeIndex newroot ;
newroot.insertKey(Ld.getKey(0),0,left,right);
root = &newroot;
printnode(root);// prints correct values
....
} 

。创建一个BtreeIndex newroot并使成员root指向它。打印root工作正常,但是当函数返回时,newroot被删除,root指向涅槃。如果您正确使用它,C++会照顾您删除内容。但是,如果要控制对象的生命周期,则必须使用 newdelete .例如

 Status BtreeBuilder::insertBuilderKey(KeyId k){
....
root = new BtreeIndex();
root->insertKey(Ld.getKey(0),0,left,right);
printnode(root);// prints correct values
....
} 

另一方面,如果BtreeBuilder"拥有"BtreeIndex,为什么不存储对象而不是指针? 即

BtreeIndex root; 
Status BtreeBuilder::insertBuilderKey(KeyId k){
....
root.insertKey(Ld.getKey(0),0,left,right);
....
}