C ++类变量不保留值

时间:2015-04-23 13:36:00

标签: c++

我最近开始用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的值,即使它是一个类变量?

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

4 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

当您尝试插入树时:

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);
....
}