下面的代码只是一个向其中插入节点的二叉树。
当我运行下面的代码时,它会抛出错误(在树的插入方法中)
“第 135 行:字符 35:错误:从以下位置分配给‘节点 *’ 'const Node *' 丢弃限定符 on.left = &add"
,有人告诉我发生这种情况是因为我试图将一个常量分配给一个非常量,这据说是不允许的。
但是由于某种原因,在Tree的构造函数中,我还使用成员初始化列表将常量引用分配给非常量成员变量Root,但这里没有抛出错误。
我对这种不一致感到困惑。我关于常量限定符的教科书和 cpp 参考页没有说明为什么成员初始化列表允许我将常量分配给非常量。为什么我可以将常量变量分配给非常量变量,但其他时候却不能?在什么情况下可以将常量赋值给非常量?
#include <sstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
template <typename T>
struct Node {
T val;
Node* left;
Node* right;
Node (const T &val) : val(val), left(nullptr), right(nullptr) {
}
};
template <typename T>
class Tree {
public:
Node<T> root;
Tree(const Node<T>& r) : root(r) { //why no error here? I'm also discarding qualifier!
std::cout<< "why no error?"<<std::endl;
}
void insert(const Node<T> &add) {
Node<T>& on = root;
while (true) {
if (add.val < on.val) {
if (on.left == nullptr) {
on.left = &add; //why error here????!!!!
return ;
} else {
on=on->left;
}
} else {
if (on.right == nullptr) {
on.right=&add;
return ;
} else {
on=on->right;
}
}
}
return ;
}
};
int main() {
using namespace std;
Tree<int> mytree(Node<int>(15));
mytree.insert(Node<int>(2));
cout<<"code finished without undefined behavior"<<endl;
return 0;
}
不将 const 分配给非 const 的规则是因为这样做将允许您修改 const 对象。例如
const int one = 1;
const int* ptr = &one;
int* bad = ptr; // not really allowed
*bad = 2; // changes the const object `one`
但是你描述的另一种情况是不同的
template <typename T>
class Tree {
public:
Node<T> root;
Tree(const Node<T>& r) : root(r) {}
这里
r
是对一个对象的 const 引用,该对象用于初始化 一个完全不同的对象,称为 root
。如果您随后更改 root
,它对 r
引用的对象根本没有影响。所以这里const
没有问题。