2012-02-29 159 views
17

我决定查看是否为成员分配引用会使成员成为引用。我写了下面的代码片段来测试它。有一个简单的类Wrapperstd::string作为成员变量。我在构造函数中采取const string&并将其分配给公共成员变量。后来在main()方法中我修改了成员变量,但是我传递给构造函数的string保持不变,怎么回事?我想在Java中,变量会发生变化,为什么不在这段代码中?在这种情况下,引用的工作原理如何?通过引用传递给构造函数

#include <iostream> 
#include <string> 
using namespace std; 

class Wrapper 
{ 
public: 
    string str; 

    Wrapper(const string& newStr) 
    { 
     str = newStr; 
    } 
}; 

int main (int argc, char * const argv[]) 
{ 
    string str = "hello"; 
    cout << str << endl; 
    Wrapper wrapper(str); 
    wrapper.str[0] = 'j'; // should change 'hello' to 'jello' 
    cout << str << endl; 
} 
+2

C++中的类型是你的命令,他们不会神奇地变成别的东西。你说'string',并且你得到一个'string'。如果你想参考,你会说'string&'。 – 2012-02-29 21:38:12

+0

你滥用人们的太简单的问题:) – Mikhail 2012-02-29 21:39:20

+2

在Java中,变量不会改变,因为代码甚至没有编译;不允许修改Java中的字符串。 – 2012-02-29 21:40:16

回答

22

要分配在构造函数的引用,你需要有一个参考成员

class A{ 
    std::string& str; 
public: 
    A(std::string& str_) 
    : str(str_) {} 
}; 

STR现在是你传递的值的参考。同样适用于常量裁判

class A{ 
    const std::string& str; 
public: 
    A(const std::string& str_) 
    : str(str_) {} 
}; 

然而不要忘记,一旦引用被赋值,它就不能被改变,所以如果赋值需要对str进行更改,那么它必须是一个指针。

5

因为Wrapper::str不是参考,所以它是一个独立的对象。所以当你做str = newStr,你是复制的字符串。

1

您应该声明Wrapper::strstring&,而不是string

3

你需要使用一个初始化,并宣布str为基准为:

class Wrapper { 
public: 
    string &str; 

    Wrapper(string& newStr) 
     : str(newStr) { 
    } 
}; 

你写它的方式,你正在做的是复制引用您传递给constuctor值。你没有保存参考。通过将引用声明为类成员并使用对另一个字符串实例的引用对其进行初始化,您将获得您正在查找的行为。

+1

您的代码尝试使用引用到const来初始化引用到可变。 – 2012-02-29 22:19:31

+0

固定...这就是我从OP中盲目复制的结果。 – andand 2012-02-29 22:31:26

5
class Wrapper 
{ 
public: 
    string& str; 

    Wrapper(string& newStr) : str(newStr) {} 
}; 

注意,你不能接受const string&并将其存储在一个string&,你会在这样做失去常量,正确性。

1

您的主体变量是std::string

您的参数变量为const std::string&

引用中的const始终是“低级常量”,这意味着它会修改对象的类型而不是实际对象。

相比之下,“顶级常量”修改实际对象。请阅读C++ Primer on Top level const以进行说明。

这是你的任务看起来如何,当你传递参数,如:

const std::string& = std::str; //Values are ommited 
// i.e const std::string newStr = std::string str 

您有non-const value这是可以接受初始化const type reference。您不应该使用该参考来更改std::string str的值。而且,如果您尝试在构造函数中更改newStr的值,那么将收到编译错误

接下来你做的构造,这也是可以接受中另一项任务:

std::string = const std::string 

wrap.str[0]没有strmain改变的事实是,尽管参考使用实例class strclass str有其自己的对象,并没有链接到main str。在参数中使用该参考仅将该参数链接到main str;不是main strclass str

如果您的类变量被引用,那么它可能已经改变。

相关问题