我试图更好地理解C ++中指针和引用之间的差异。来自Java背景,我期待C ++中的引用类似;我期望指针减去指针算术。但是,我一直很失望,有时候很困惑。经过一些阅读后,我认为我理解引用是没有指针算法的指针,永远不能设置为NULL。为了测试我学到的东西,我决定开始编码。但是,我遇到了这个问题,我不明白为什么我的代码无法编译。
以下是我的尝试:
3 void test(biNode*& bn)
4 {
5 string& s("another test");
6 bn = new biNode(s);
7 printf("Just Checking: %s\n", bn->getObject().c_str());
8 }
9
10 int main()
11 {
12 biNode* bn;
13 test(bn);
14 printf("Just Checking: %s\n", bn->getObject().c_str());
15 }
这是我的'biNode'标题:
1 #include <string>
2 #include <iostream>
3
4 using namespace std;
5
6 class biNode
7 {
8 public:
9 biNode(string& s);
10 string& getObject();
11 private:
12 string& obj;
13 };
有相应的定义:
1 biNode::biNode(string& s) : obj(s)
2 {}
3 string& biNode::getObject()
4 {
5 return this->obj;
6 }
尝试编译它会产生以下错误:
./test.cpp: In function `void test(biNode*&)':
./test.cpp:5: error: invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'const char*'
我不明白'string&amp; s(“另一个测试”);'无效。有人可以解释一下吗?
提前致谢!
答案 0 :(得分:2)
您需要学习的另一个参考规则是临时(rvalues)只能绑定到const
个引用。绑定后,临时的生命周期将延长,以匹配绑定的引用的生命周期。
string& s("another test");
在这里,您尝试将rvalue(字符串文字"another test"
)绑定到s
,这是非const
引用。
将行更改为
string const& s("another test");
它将编译。
此外,在您的示例中,使s
成为引用类型没有任何好处。所以你也可以将行改为
string s("another test");
并且代码将按预期编译和工作。
答案 1 :(得分:1)
除了相同类型的现有对象之外,您不能初始化非const引用,然后引用将对其进行别名。但是你的类biNode
也包含一个引用成员,所以你只能用一个对象存在一个biNode
实例,该对象的存在时间至少与节点实例本身一样长!
以下是一个示例,演示如何以理智的方式使用biNode
:
int main()
{
std::string s("Hello");
for (int i = 0; i != 10; ++i)
{
biNode bn(s);
// more stuff
}
}
test
函数的合理版本可能如下所示:
biNode test(std::string & s)
{
return biNode(s);
}
int main()
{
std::string s("World");
auto bn = test(s);
}
答案 2 :(得分:0)
您似乎遇到的混淆的主要原因是参考是什么。在C ++中,引用是现有对象的别名。引用必须始终引用一个对象,并且它别名的对象始终是相同的(不能重置)。绑定对象的引用是为该对象创建别名。为此,您首先需要一个适当类型的对象,标准中存在一个显式异常:您可以将const
引用绑定到临时(即创建对象的表达式)。