C ++中引用指针

时间:2015-12-07 16:08:12

标签: c++

我一直都知道通过引用传递变量只意味着变量将保持对函数中变量的任何更改,并且函数的工作不会改变,但在这种情况下,函数完全有效不同。 唯一的区别在于两个代码中此函数的定义。 void rotate(node *&); void rotate(node *);

这是第一个代码

#include<iostream>
#include<stack>
using namespace std;
struct node
{
    char data;
    node* left;
    node* right;
    node()
    {
        left=0;
        right=0;
    }
};
class AVL
{
private:
    node* root;
public:
    AVL()
    {
        root=NULL;
    }
    void initialize();
    void rotate(node*&);
    node*& return_n()
    {
        return root->left;
    }
    void traverse();

};
void AVL::initialize()
{
    root=new node;
    root->data='a';
    root->left=new node;
    root->left->data='b';
    root->left->left=new node;
    root->left->left->data='c';
    root->left->left->left=new node;
    root->left->left->left->data='d';
}
void AVL::traverse()
{
    node* temp=root;
    if(temp!=0)
    {
        stack<node*> s;
        s.push(temp);
        while(!s.empty())
        {
            temp=s.top();
            s.pop();
            cout<<endl<<temp->data<<endl;
            if(temp->left!=0)
            {
                s.push(temp->left);
                cout<<"Left: "<<s.top()->data<<endl;
            }
            else
            {
                cout<<"Left: NULL"<<endl;
            }
            if(temp->right!=0)
            {
                s.push(temp->right);
                cout<<"Right: "<<s.top()->data<<endl;
            }
            else
            {
                cout<<"Right: NULL ";
            }
        }
    }
}
void AVL::rotate(node*& temp)
{
    node* temp2=temp->left;
    cout<<endl<<"Step1"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    temp->left=temp2->right;
    cout<<endl<<endl<<endl;
    cout<<endl<<"Step2"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    temp2->right=temp;
    cout<<endl<<endl<<endl;
    cout<<endl<<"Step3"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    temp=temp2;
    cout<<endl<<endl<<endl;
    cout<<endl<<"Step4"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    system("pause");
}
int main()
{
    AVL obj;
    obj.initialize();
    obj.traverse();
    obj.rotate(obj.return_n());
    return 0;
}

这是第二个代码

#include<iostream>
#include<stack>
using namespace std;
struct node
{
    char data;
    node* left;
    node* right;
    node()
    {
        left=0;
        right=0;
    }
};
class AVL
{
private:
    node* root;
public:
    AVL()
    {
        root=NULL;
    }
    void initialize();
    void rotate(node*);
    node*& return_n()
    {
        return root->left;
    }
    void traverse();

};
void AVL::initialize()
{
    root=new node;
    root->data='a';
    root->left=new node;
    root->left->data='b';
    root->left->left=new node;
    root->left->left->data='c';
    root->left->left->left=new node;
    root->left->left->left->data='d';
}
void AVL::traverse()
{
    node* temp=root;
    if(temp!=0)
    {
        stack<node*> s;
        s.push(temp);
        while(!s.empty())
        {
            temp=s.top();
            s.pop();
            cout<<endl<<temp->data<<endl;
            if(temp->left!=0)
            {
                s.push(temp->left);
                cout<<"Left: "<<s.top()->data<<endl;
            }
            else
            {
                cout<<"Left: NULL"<<endl;
            }
            if(temp->right!=0)
            {
                s.push(temp->right);
                cout<<"Right: "<<s.top()->data<<endl;
            }
            else
            {
                cout<<"Right: NULL ";
            }
        }
    }
}
void AVL::rotate(node* temp)
{
    node* temp2=temp->left;
    cout<<endl<<"Step1"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    temp->left=temp2->right;
    cout<<endl<<endl<<endl;
    cout<<endl<<"Step2"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    temp2->right=temp;
    cout<<endl<<endl<<endl;
    cout<<endl<<"Step3"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    temp=temp2;
    cout<<endl<<endl<<endl;
    cout<<endl<<"Step4"<<endl;
    cout<<endl<<"Temp"<<temp->data<<endl;
    cout<<endl<<"Temp2"<<temp2->data<<endl;
    traverse();
    system("pause");
}
int main()
{
    AVL obj;
    obj.initialize();
    obj.traverse();
    obj.rotate(obj.return_n());
    return 0;
}

2 个答案:

答案 0 :(得分:2)

通过引用传递obj.return_n(),您可以为函数提供修改此引用的可能性。

在第一段代码中,遇到这些行:

temp=temp2;
cout<<endl<<endl<<endl;
cout<<endl<<"Step4"<<endl;
cout<<endl<<"Temp"<<temp->data<<endl;
cout<<endl<<"Temp2"<<temp2->data<<endl;
traverse();

temproot->left中对AVL::traverse()的引用,在traverse()调用之前会被修改。在第二种情况下,temp是副本,root->left 已修改,然后traverse的行为不像以前那样。

因此存在差异。

您应该学会正确使用引用。您可以使用 const 关键字修改它们。我想补充一点,对指针的引用看起来很糟糕。

答案 1 :(得分:2)

通过引用传递指针的简单问题的代码太多。当您通过引用传递指针时,可以在函数中修改指针本身,并保留更改。当传递的指针通过值传递时,对指针的修改将丢失,但通过该指针修改的任何对象将保持修改。简单的例子:

int glob_x;
int glob_y;

void modify_ptr(int*& ptr) {
    ptr = &glob_x;
}

void modify_value(int* ptr) {
   *ptr = 42;
   ptr = &glob_y;
}

int main() {
  int* p;
  modify_ptr(p); // after this line p points to glob_x
  modify_value(p); // now glob_x is 42, but p is still pointing to glob_x
  *p = 56; // glob_x is now 56
}