Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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++_Pointers_Memory_Memory Management_Scope - Fatal编程技术网

C++;引用和现有范围 我开始研究C++中的引用,并且我有一个围绕引用和范围的小查询,对此,最好创建一个例子:

C++;引用和现有范围 我开始研究C++中的引用,并且我有一个围绕引用和范围的小查询,对此,最好创建一个例子:,c++,pointers,memory,memory-management,scope,C++,Pointers,Memory,Memory Management,Scope,假设我在“BankDatabase.cpp”中有一个方法,它通过引用获取银行记录并将其添加到数据结构(也通过引用) 如果我运行这样的方法: void TestAddRecord( BankDatabase& bankDatabase ) { BankRecord bankRecord { "John", "Doe", 9999 } bankDatabase.AddRecord( bankRecord ); } 在我看来,“bankRecord”不在范围内(它的两个字符串

假设我在“BankDatabase.cpp”中有一个方法,它通过引用获取银行记录并将其添加到数据结构(也通过引用)

如果我运行这样的方法:

void TestAddRecord( BankDatabase& bankDatabase )
{
    BankRecord bankRecord { "John", "Doe", 9999 }
    bankDatabase.AddRecord( bankRecord );
}
在我看来,“bankRecord”不在范围内(它的两个字符串和int也不在范围内),因此在“TestAddressRecord”方法结束时从内存中清除,留下“bankDatabase”指向一些空内存


如果是这样的话,这种情况的公认标准/解决方案是什么?必须按值传递东西似乎有点疯狂…

在这种情况下,按值传递似乎是一种方式。分配一个新的
BankRecord
指针也会起作用。通过引用存储东西不是很好


但是,如果我没有弄错的话,您的两个字符串和int不会丢失,因为它们存在于堆栈中,并且不会被释放。但是bankRecord仍将丢失。

解决这些问题的最佳方法是在调试器中逐步检查代码,并查看向量在附加变量时的作用。当您进入数据结构的Append函数时,请特别注意构造函数调用。因为我不知道您的底层数据结构,所以要告诉您更多信息有点困难。我现在假设它是一个std::vector,除非另有说明

您可能会惊讶地发现,通过函数传递的引用并没有说明函数何时进入范围和何时超出范围。我经常把C++引用看作指针,它不需要nulpPTR检查< /强> 只要引用被复制到向量中,或者没有因为指向的变量被破坏而超出范围,代码就可以正常工作。如果引用的是特定情况下堆上的成员变量或内存,则引用不会超出范围

如果在堆栈上声明对在堆栈上创建的变量的引用,然后将其附加到向量,则会出现范围问题

如果您有C++11并且编译器支持移动语义,那么还应该查看emplace()


简而言之,在这里您可以做的最重要的事情是逐步浏览代码,并查看调用了哪些构造函数。这将为您提供所需的答案。

我关心的是它似乎不是特别灵活,因此,例如,如果我要添加两次记录-bankDatabase.AddRecord(bankRecord);bankDatabase.AddRecord(bankRecord);-然后,他们会被期望共享一个引用,但如果给出一个“传递值”,他们就不会了?@PaulRenton哦,好吧!我一直认为引用是指针的糖,这几乎不是错的。因此,我们需要知道存储数据结构,以判断引用是否被复制?是的,例如,如果AddRecord具有多个覆盖,会怎么样,就像许多常见的数据结构一样。如果AddRecord的签名看起来像-AddRecord(varType object&&),它将使用移动语义,不会像典型的传递值append那样多次调用构造函数。此外,一些数据结构在内部执行POD数据检查,只执行memcopy。有时候,挑战你的假设,一步一步地浏览代码,看看会发生什么是非常重要的。这是一个很好的实践。@D.nathanel如果您想看到我所说的示例,请查看所有添加元素的std::vector函数。首先看看emplace、push_back和其他之间的区别。@D.Nathanel最后一件值得一提的事情。指针和引用之间的一大区别是,对对象的引用只能指定一个,不能指定给nullptr(除非您执行了一个邪恶的把戏)。一旦一个引用被分配给一个r值,它将使用所有的objects操作符,包括赋值操作符,正如您可能猜到的,赋值操作符将改变事物的工作方式,而不是将指针传递到数据结构中,在将同一指针从一个对象分配到另一个对象时,上述操作符不应用。希望这有帮助
void TestAddRecord( BankDatabase& bankDatabase )
{
    BankRecord bankRecord { "John", "Doe", 9999 }
    bankDatabase.AddRecord( bankRecord );
}