字符串引用来自String Literal C ++

时间:2011-09-14 20:44:21

标签: c++ string literals

我希望有人可以帮助回答有关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足以在调用foo()之后将字符串文字“exit”调整为“axit”,我相信在案例1中输出仍将是“退出” 3,并在案例2中“退出”。这是正确的吗?

B)在第1和第3种情况下,我认为因为该方法要求一个String(即使它是案例1中的引用),所以对字符串构造函数有一个隐式调用(它接受const char *) ,并且构造函数总是复制,而不是引用。 (见cplusplus.com string page)这是否正确(尤其是总是)?

C)在案例1中,如果我初始化了一个有字符串&amp;的新类。我分配了文本变量的属性,当我们离开范围时,这个引用会指向坏内存吗? IE,当我们达到4时,我相信发生了以下情况(假设foo(const string&amp; 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,其他人的建议?)自己回答这个问题的一些想法会很棒。我花了很多时间尝试这样做,我想听听别人说的话。

1 个答案:

答案 0 :(得分:1)

A)我对OllyDbg一无所知,但在所有情况下,std::ostream都会在text返回之前使其成为foo的副本,因此任何更改调用后的变量不会影响输出 B)是的,在隐式构造参数期间,string构造函数将始终使其自己的char*副本。
C)是的,当您拨打foo时,会自动创建并使用string,并在通话结束后将其销毁,让bar指向无效的内存。
D)你是对的。 foo(const char* text)指针的副本复制到数据中,但复制数据。但由于operator<<(ostream, char*)复制了数据,因此更改数据会影响输出。我不明白为什么你不能通过const char*文字。
E)上课,阅读教程或阅读规范。对于这类问题,试验和错误不会让您在标准库中走得更远。

对于这些,概念是封装。 C ++标准库中的对象都是封装的,因此任何操作的结果都是您所期望的,并且真的很难意外地弄乱它们的内部以使事情失败或泄漏。如果你告诉ostreamchar *打印数据,它会(A)立即执行,或者(B)在它返回之前制作它自己的副本,以防你弄乱{{1}以后。

相关问题