C++;类变量不保留值 我最近开始用C++编程(用java做了)。我遇到一个类变量不保留其值的问题

C++;类变量不保留值 我最近开始用C++编程(用java做了)。我遇到一个类变量不保留其值的问题,c++,C++,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

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
的值,即使它是一个类变量


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

b重新索引newrootBtreeBuilder::insertBuilderKey
中,code>在堆栈上创建了一个
BtreeIndex
,但是一旦方法完成,保存该变量的stackframe就会被销毁,因此您的变量也会被销毁

您需要在堆上创建
BtreeIndex
BtreeIndex*newroot=newbtreeindex()


有关更多信息,请参阅。

b重新索引newrootBtreeBuilder::insertBuilderKey
中,code>在堆栈上创建了一个
BtreeIndex
,但是一旦方法完成,保存该变量的stackframe就会被销毁,因此您的变量也会被销毁

您需要在堆上创建
BtreeIndex
BtreeIndex*newroot=newbtreeindex()


有关更多信息,请参阅。

您拥有类memeber
b reenode root
并从堆栈上的变量为其赋值:
BtreeIndex newroot
。当代码退出作用域时,此变量将被销毁(退出
insertBuilderKey(keyidk){…}
函数。如果需要分配新根,请在heap
BtreeIndex newroot=new BtreeIndex()中创建它
然后继续。不要忘了删除之后需要的内容。

您有类memeber
b重节点根;
并且您从堆栈上的变量为其赋值:
b重索引newroot
。当代码退出作用域时,该变量将被销毁(exits
insertBuilderKey(KeyId k){…}
函数。如果需要分配新根,请在堆中创建它。
BtreeIndex newroot=new BtreeIndex()
然后继续。不要忘记删除以后需要的内容。

尝试插入树时:

Status BtreeBuilder::insertBuilderKey(KeyId k){
....
BtreeIndex newroot ;
newroot.insertKey(Ld.getKey(0),0,left,right);
root = &newroot;
printnode(root);// prints correct values
....
} 
…您创建一个
b重新索引newroot
并使成员
root
指向它。打印
root
工作正常,但当函数返回
newroot
时,会删除
root
并指向涅磐。 如果你正确地使用它,C++会关心删除的东西。但是,如果你想控制对象的生命周期,你必须使用<代码>新< /COD>和<代码>删除< /代码>。
 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);
....
} 

尝试插入树时:

Status BtreeBuilder::insertBuilderKey(KeyId k){
....
BtreeIndex newroot ;
newroot.insertKey(Ld.getKey(0),0,left,right);
root = &newroot;
printnode(root);// prints correct values
....
} 
…您创建一个
b重新索引newroot
并使成员
root
指向它。打印
root
工作正常,但当函数返回
newroot
时,会删除
root
并指向涅磐。 如果你正确地使用它,C++会关心删除的东西。但是,如果你想控制对象的生命周期,你必须使用<代码>新< /COD>和<代码>删除< /代码>。
 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);
....
} 

默认情况下,局部变量具有自动存储持续时间,并且在退出作用域(例如,从函数返回)时不再存在

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


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

本地变量默认为自动存储持续时间,并且在退出作用域时不再存在(例如,从功能返回)

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


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

最小但完整的代码?简单:指针不保留值
root=&newroot;
root
保存到的地址一个具有自动存储持续时间的局部变量,因此它在
insertBuilderKey
exitPut上失效。另一种方法是保留
root
的值。它仍然指向
newroot
曾经存在的地址。但是,正如Piotr所解释的,一旦
insertBuilderKey()
退出,
newroot
不再存在,该空间可自由用于其他用途。感谢,它使我的概念变得清晰,最小但完整的代码?很简单:指针不保留值
root=&newroot;
root
持有一个具有自动存储持续时间的局部变量地址,因此无效在
insertBuilderKey
exitPut另一种方式-保留
root
的值。它仍然指向
newroot
曾经存在的地址。但是,正如Piotr所解释的,一旦
insertBuilderKey()
退出,
newroot
已不存在,该空间可自由用于其他用途。谢谢,它让我的概念变得清晰