Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;使用对字符串的引用作为别名_C++_String - Fatal编程技术网

C++ C++;使用对字符串的引用作为别名

C++ C++;使用对字符串的引用作为别名,c++,string,C++,String,使用对象的引用作为别名是否总是安全的?例如,字符串: std::string test; std::string &reftest( test ); std::cout << "test before: " << test << "\n"; std::cout << "reftest before: " << reftest << "\n"; reftest = "abc"; std::cout << "

使用对象的引用作为别名是否总是安全的?例如,字符串:

std::string test;
std::string &reftest( test );
std::cout << "test before: " << test << "\n";
std::cout << "reftest before: " << reftest << "\n";
reftest = "abc";
std::cout << "test after: " << test << "\n";
std::cout << "reftest after: " << reftest << "\n";
std::字符串测试;
标准:字符串和参考测试(测试);

std::cout是。它们都指向内存中的同一位置。输出每个变量的地址,您将看到这一点。

是。它们都指向内存中的同一位置。输出每个变量的地址,您将看到这一点。

将引用视为昵称会有所帮助。即使您说的是
reftest
,您仍然指的是
test
。总之,是的

注意有一些限制。例如,以下内容不是标准:

std::string &reftest( std::string("test") );
但是这个

const std::string &reftest( std::string("test") );

是,因为常量引用可以绑定到临时引用,而非常量引用不能绑定到临时引用。

将引用视为昵称会有所帮助。即使您说的是
reftest
,您仍然指的是
test
。总之,是的

注意有一些限制。例如,以下内容不是标准:

std::string &reftest( std::string("test") );
但是这个

const std::string &reftest( std::string("test") );

是,因为常量引用可以绑定到临时引用,而非常量引用不能绑定到临时引用。

是。这两个名称指的是同一个对象

虽然名字之间有些不同。例如,
decltype(reftest)
不会产生与
decltype(test)
相同的类型


正如其他人所指出的,有一些方法可以获得一个不合法使用的引用,但在这些情况下,这是因为该引用不是合法变量的别名。

是的。这两个名称指的是同一个对象

虽然名字之间有些不同。例如,
decltype(reftest)
不会产生与
decltype(test)
相同的类型

正如其他人所指出的,有一些方法可以获得一个不合法使用的引用,但在这些情况下,这是因为该引用不是合法变量的别名。

它们是相同的字符串,就像一个叫罗伯特的人被称为鲍勃一样

就像你说的,同一个东西只有两个名字,一个别名。

它们是同一个字符串,就像一个叫罗伯特的人叫鲍勃一样


正如您所说,同一事物只有两个名称,一个别名。

在您的示例中,是的,但存在陷阱:

struct X {
  std::string& s;
  X(std::string& s) : s(s) {}
};
struct Y {
  std::string s;
};

int main() {
  Y* y = new Y();
  X x(y->s);
  delete y;
  // now, x.s is dangling, as it refers to y->s, which is gone.
  std::cout << x.s << std::endl; // <- segfault
  return 0;
}
struct X{
std::string&s;
X(std::string&s):s(s){}
};
结构{
std::字符串s;
};
int main(){
Y*Y=新的Y();
X(y->s);
删除y;
//现在,x.s是悬挂的,因为它指的是y->s,它已经消失了。

在您的示例中,std::cout是的,但存在陷阱:

struct X {
  std::string& s;
  X(std::string& s) : s(s) {}
};
struct Y {
  std::string s;
};

int main() {
  Y* y = new Y();
  X x(y->s);
  delete y;
  // now, x.s is dangling, as it refers to y->s, which is gone.
  std::cout << x.s << std::endl; // <- segfault
  return 0;
}
struct X{
std::string&s;
X(std::string&s):s(s){}
};
结构{
std::字符串s;
};
int main(){
Y*Y=新的Y();
X(y->s);
删除y;
//现在,x.s是悬挂的,因为它指的是y->s,它已经消失了。


std::cout这就是它的用途。“拥有”相同的字符串?它们是相同的
string
…这正是引用的概念。只要被引用的对象仍在范围内,它总是安全的。这就是它的用途。“拥有”相同的字符串?它们是相同的
string
…这正是引用的概念。只要被引用的对象仍在范围内,它总是安全的。@BenjaminLindley变量声明。如问题中所述。是否
std::string&reftest=std::string(“test”)
更清楚?我已将此标记为正确。虽然其他答案都正确,但这似乎是最正确的。您能详细说明为什么前者不标准吗?我的示例代码与前者类似吗?@test问题在于
std::string(“test”)产生临时对象,然后将引用设置为临时对象,然后临时对象被破坏,引用不再有效。在第二种情况下,使用<代码> const STD::String和< /Cord>,引用仍然有效,因为C++中有一个特殊的规则,用临时表初始化const引用。y对象延长临时对象的生存期,以便在常量引用存在时不会销毁临时对象。该规则仅适用于常量引用,而不适用于引用。@bames53谢谢。这应该是答案的一部分,即如果对象是临时对象,则引用必须是常量,因为对临时对象确保其生存期。@BenjaminLindley变量声明。如问题中所述。将
std::string&reftest=std::string(“测试”)
更清楚?我已将此标记为正确。虽然其他答案都正确,但这似乎是最正确的。您能详细说明为什么前者不标准吗?我的示例代码与前者类似吗?@test问题在于
std::string(“test”)产生临时对象,然后将引用设置为临时对象,然后临时对象被破坏,引用不再有效。在第二种情况下,使用<代码> const STD::String和< /Cord>,引用仍然有效,因为C++中有一个特殊的规则,用临时表初始化const引用。y对象延长临时对象的生存期,以便在常量引用存在时不会销毁临时对象。该规则仅适用于常量引用,而不适用于引用。@bames53谢谢。这应该是答案的一部分,即如果对象是临时对象,则引用必须是常量,因为对临时对象保证了它的寿命。当你想到它时,说它们在谈论一件事时是一样的,其实有点好笑。是的,相同的字符串会更好。:-)在所有答案中,这是我最容易理解的。当你想到一件事时,说它们是一样的,其实有点好笑是的,相同的字符串会更好。:-)在所有的答案中,这是我最容易理解的。谢谢,我会注意的