我最近开始用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
的值,即使它是一个类变量?
这个问题的解决方案是什么。
答案 0 :(得分:4)
BtreeIndex newroot ;
中的{p> BtreeBuilder::insertBuilderKey
在堆栈上创建了BtreeIndex
,但是一旦方法完成就会销毁保存该变量的堆栈帧,因此您的变量也会被销毁。
您需要在堆上创建BtreeIndex
:BtreeIndex* 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 ++会照顾你删除的东西。但是,如果要控制对象的生命周期,则必须使用new
和delete
。例如。
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);
....
}