C++ C++;通过引用移动,值不会';你不会变吗?

C++ C++;通过引用移动,值不会';你不会变吗?,c++,class,pointers,reference,C++,Class,Pointers,Reference,我在我的树类中编写了以下方法: public: node<T> *root; template<class T> node<T> *tree<T>::insert(node<T> *p, const T &key) { if (p == nullptr) { p = new node<T>(key); } //Some code } 很明显,我是通过引用而不是通过值移

我在我的
类中编写了以下方法:

public:
    node<T> *root;

template<class T>
node<T> *tree<T>::insert(node<T> *p, const T &key) {
    if (p == nullptr) {
       p = new node<T>(key);
    }
    //Some code
}
很明显,我是通过引用而不是通过值移动的,因为我给了一个指向根节点的insert指针。(根是指向根的指针)


我希望有人能清楚地解释我做错了什么,以及如何解决这个问题,因为我被困在这个问题上了一天。

因为
p
不是
根。使用root作为参数调用
insert
函数将复制指向
p
的指针,这不会使
p
root
的变量相同。因此对
p
的更改对
root
没有影响

如果要使is so
p
root
的变量相同,则必须使用引用

template<class T>
node<T> *tree<T>::insert(node<T> *&p, const T &key) {
模板
节点*树::插入(节点*&p、常量T和键){

现在指针
p
是对用来调用
insert
的任何指针的引用,因此对
p
的更改将更改原始指针(
root
).

因为
p
不是
root
。调用
insert
函数并以root作为参数复制指向
p
的指针,它不会使
p
成为与
root
相同的变量。因此对
p
的更改对
root
没有影响

如果要使is so
p
root
的变量相同,则必须使用引用

template<class T>
node<T> *tree<T>::insert(node<T> *&p, const T &key) {
模板
节点*树::插入(节点*&p、常量T和键){

现在指针
p
是对用来调用
insert
的任何指针的引用,因此对
p
的更改将更改原始指针(
root
).

您是通过值传递
t1.root
,而不是通过引用或指针。因此,函数
insert
获取变量
t1.root
的自身副本,更改此副本不会更改原始变量

要解决此问题,可以通过引用或指针传递,而不是通过值传递

要通过指针传递,可以将函数
insert
更改为以下内容:

node<T> *tree<T>::insert(node<T> **pp, const T &key) {
    if (*pp == nullptr) {
       *pp = new node<T>(key);
    }
    //Some code
}
这样,您将传递
t1.root的地址,以便函数可以修改原始值

或者,您可以通过引用传递
t1.root
,如下所示:

t1.insert(&t1.root,7);
node<T> *tree<T>::insert(node<T> *&p, const T &key) {
    if (p == nullptr) {
       p = new node<T>(key);
    }
    //Some code
}
node*tree::insert(node*&p,const T&key){
如果(p==nullptr){
p=新节点(键);
}
//一些代码
}

在这种情况下,在调用函数时,不必在代码根>前加上<代码>和>代码,也不必在函数体中使用“代码> */CODE”进行撤销引用。这与使用双指针有效地相同,但C++处理了撤销引用并将地址传递给您,因此您没有。您正在通过值传递

t1.root
,而不是通过引用或指针。因此,函数
insert
获得变量
t1.root
的自己副本,更改此副本不会更改原始变量

要解决此问题,可以通过引用或指针传递,而不是通过值传递

要通过指针传递,可以将函数
insert
更改为以下内容:

node<T> *tree<T>::insert(node<T> **pp, const T &key) {
    if (*pp == nullptr) {
       *pp = new node<T>(key);
    }
    //Some code
}
这样,您将传递
t1.root的地址,以便函数可以修改原始值

或者,您可以通过引用传递
t1.root
,如下所示:

t1.insert(&t1.root,7);
node<T> *tree<T>::insert(node<T> *&p, const T &key) {
    if (p == nullptr) {
       p = new node<T>(key);
    }
    //Some code
}
node*tree::insert(node*&p,const T&key){
如果(p==nullptr){
p=新节点(键);
}
//一些代码
}

在这种情况下,在调用函数时,不必在代码根>前加上<代码>和>代码,也不必在函数体中使用“代码> */CODE”进行撤销引用。这与使用双指针有效地相同,但C++处理了撤销引用并将地址传递给您,因此您没有。不必担心。

参数
p
是按值传递的;实际上,它是
t1.root
的副本。调用方看不到函数中此参数的更改。@IgorTandetnik为什么按值传递pointer@user128250指针也是值。对于指针,没有特殊规则规定它们不能作为值传递(这是一个非常常见的误解)。即使指针是按值复制的,它仍然具有相同的内部值(指向相同的对象)@user128250其实很简单,只是新手习惯于把事情复杂化。我相信你会同意你有两个变量
p
root
,你用
p=…
更改其中一个。为什么要更改另一个变量?如果它们都是整数,它会更改另一个变量吗?为什么指针有什么不同吗?事实是指针没有什么不同。参数
p
是按值传递的;实际上,它是
t1.root
的副本。调用方看不到函数中此参数的更改。@IgorTandetnik为什么按值传递它是pointer@user128250指针也是值o针对指针的特殊规则,该规则表示它们不是作为值传递的(这是一个极为常见的误解)。即使指针是按值复制的,它仍然具有相同的内部值(指向相同的对象)@user128250其实很简单,只是新手习惯于把事情复杂化。我相信你会同意你有两个变量
p
root
,你用
p=…
更改其中一个。为什么要更改另一个变量?如果它们都是整数,它会更改另一个变量吗?为什么指针有什么不同吗?事实是指针没有什么不同。但我不明白