来自String Literal c++的String引用

String Reference from String Literal C++

本文关键字:String 引用 Literal 来自 c++      更新时间:2023-10-16

我希望有人能帮助回答一个关于c++中的字符串的问题。我试图从这里剥离任何无关的代码,所以它不会编译(缺少命名空间,定义等)。这不是一个"bug"问题。如果需要工作代码示例,请指定您想要的代码(针对哪个问题),我很乐意提供更详细的内容。

//Foo.c
#define EXIT "exit"
Bar* bar; //See question C
//1
foo(const string& text) {
    cout << text;
    bar = new Bar(text); //See question C
}
//2
foo(const char* text) {
    cout << text;
}
//3
foo(string text) {
    cout << text;
}
int main() {
....
    { foo(EXIT); } //braces for scope, see question C)
    bar->print(); //4
....
}
class Bar {
    private const string& strBar;
    Bar::Bar(const string& txt) : strBar(txt) { }
    Bar::print() { cout << strBar; }
}

假设三个foo()方法中只有一个是未注释的,它们不应该被重载。我有几个问题:

A)如果我能弄清楚如何使用OllyDbg足够好地将字符串字面量"exit"修改为"exit"在调用foo()之后,我相信在情况1和3中输出仍然是"exit",而在情况2中是"exit"。这是正确的吗?

B)在情况1和3中,我认为,因为方法要求一个String(即使它是一个引用在情况1中),有一个隐式调用字符串构造函数(它接受const char*),构造函数总是复制,从不引用。(见cplusplus.com字符串页)这是正确的(特别是总是)?

C)在情况1中,如果我初始化了一个具有字符串&属性,当我们离开作用域时,这个引用会指向坏内存吗?IE,当我们到达4时,我相信下面发生了(假设foo(const string&Text)是未注释的函数):1. 为复制文本的foo(EXIT)行创建一个临时字符串对象。2. 对temp对象的引用通过bar和strBar属性传递3.一旦代码继续运行并离开调用foo(EXIT)的作用域,我相信临时字符串对象就会超出作用域并消失,这意味着strBar现在引用了一个具有未定义内容的内存区域,认为它仍然是一个字符串。

D)回到A,我相信在情况2 (foo(const char* text))中,对foo的调用引用了字面量本身,而不是副本,这就是为什么在内存中摆弄字面量会改变输出的原因。这是正确的吗?如果我继续使用const char*,我可以继续传递字面量(比如传递给Bar)吗?

E)除了"这就是它的工作方式"之外,你将如何测试这些内容?"阅读说明书"?我不需要一步一步的指导,但是一些关于我应该做什么来使用我可用的工具(Visual Studio, OllyDbg,对其他人的建议?)来回答这个问题的想法将是伟大的。我花了很多时间来做这件事,我想听听人们的意见。

A)我对OllyDbg一无所知,但在所有情况下,std::ostreamfoo返回之前制作了自己的text副本,因此调用后变量的任何更改都不会影响输出。
B)是的,在隐式构造参数期间,string构造函数总是会生成自己的char*副本。
C)是的,当你调用foo时,一个string被自动创建和使用,调用结束后,它被销毁,留下bar指向无效内存。D)你是正确的。foo(const char* text)复制指向数据的指针,但是不复制数据。但是由于operator<<(ostream, char*)复制了数据,更改数据将而不会影响输出。我不明白为什么你不能传递const char*文字。
E)参加课程,阅读教程,或者阅读说明书。尝试和错误不会让你在标准库中解决这类问题。

对于这些,概念是封装。c++标准库中的对象都是封装的,因此任何操作的结果都是您所期望的,并且真的很难意外地混淆它们的内部以使事情失败或泄漏。如果您告诉ostreamchar *处打印数据,它将(a)立即执行,或者(B)在返回之前生成自己的副本,以防您稍后与char*混淆。

相关文章: