简体   繁体   English

在 C++ 中将字符串文字传递给接受 const std::string & 的函数时会发生什么?

[英]What happens when a string literal is passed to a function accepting a const std::string & in C++?

as you can probably guess from the title, I want to understand what exactly happens when a std::string is passed to a function as a const reference, because earlier today I ran into a few situations I didn't quite understand entirely.正如您可能从标题中猜到的那样,我想了解将 std::string 作为常量引用传递给函数时究竟会发生什么,因为今天早些时候我遇到了一些我不太完全理解的情况。 Here's some code:这是一些代码:

#include <string>
#include <stdio.h>

struct Interface {
    virtual void String1(const std::string &s) = 0;
    virtual void String2(const std::string &s) = 0;
    virtual void DoSomething() = 0;
};

struct SomeClass : public Interface {
    void String1(const std::string &s) override { s1 = s.c_str(); }
    void String2(const std::string &s) override { s2 = s.c_str(); }
    void DoSomething() override { printf("%s - %s\n", s1, s2); }

private:
    const char *s1, *s2;
};

struct AnotherClass {
    AnotherClass(Interface *interface) : interface(interface) {
        this->interface->String1("Mean string literal");
    }

    void DoTheThing() {
        std::string s("Friendlich string literal");
        interface->String2(s);
        interface->DoSomething();
    }

private:
    Interface *interface = nullptr;
};

int main(int argc, char **argv) {
    SomeClass some_class;
    AnotherClass another_class(&some_class);

    another_class.DoTheThing();
}

When using const char * for s1 and s2 in SomeClass the program prints Friendlich string literal - Friendlich string literal or [some rubbish] - Friendlich string literal instead of Mean string literal - Friendlich string literal as I was expecting.当在 SomeClass 中对 s1 和 s2 使用 const char * 时,程序会打印Friendlich string literal - Friendlich string literal[some rubbish] - Friendlich string literal而不是Mean string literal - Friendlich string literal,正如我所期待的。

When switching to std::string for s1 and s2 it works as expected, printing Mean string literal - Friendlich string literal .当为 s1 和 s2 切换到 std::string 时,它按预期工作,打印Mean string literal - Friendlich string literal

What a coworker and I are guessing is that the string in the ctor of AnotherClass goes out of scope but SomeClass still has the address of the string stored because of c_str().我和一位同事猜测,AnotherClass 的 ctor 中的字符串超出了范围,但由于 c_str(),SomeClass 仍然存储了字符串的地址。

When using std::string instead of const char * for s1 and s2 it actually makes a copy, so going out of scope isn't a problem.当对 s1 和 s2 使用 std::string 而不是 const char * 时,它实际上会创建一个副本,因此超出范围不是问题。 Like this:像这样:

struct SomeClass : public Interface {
    void String1(const std::string &s) override { s1 = s; }
    void String2(const std::string &s) override { s2 = s; }
    void DoSomething() override { printf("%s - %s\n", s1.c_str(), s2.c_str()); }

private:
    std::string s1, s2;
};

So... what's really happening?那么……到底发生了什么? Why doesn't it work with const char *?为什么它不适用于 const char *? Why does it work with std::string?为什么它适用于 std::string?

When you pass a string literal to a function that accepts const std::string& , the following events occur:当您将字符串文字传递给接受const std::string&的函数时,会发生以下事件:

  • The string literal is converted to const char*字符串文字被转换为const char*
  • A temporary std::string object is created.创建了一个临时的std::string对象。 Its internal buffer is allocated, and initialized by copying the data from the const char* until the terminating null is seen.它的内部缓冲区被分配,并通过从const char*复制数据来初始化,直到看到终止的 null。 The parameter refers to this temporary object.参数指的是这个临时对象。
  • The function body runs.函数体运行。
  • Assuming the function returns normally, the temporary object is destroyed at some unspecified point between when the function returns and the end of the calling expression.假设函数正常返回,临时对象在函数返回和调用表达式结束之间的某个未指定点被销毁。

If the c_str() pointer is saved from the parameter, it becomes a dangling pointer after the temporary object is destroyed since it points into the temporary object's internal buffer.如果c_str()指针是从参数中保存的,那么在临时对象被销毁后它就变成了一个悬空指针,因为它指向临时对象的内部缓冲区。

A similar problem will occur if the function accepts std::string .如果函数接受std::string也会出现类似的问题。 The std::string object will be created when the function is called and destroyed when the function returns or soon afterward, so any saved c_str() pointer will become dangling. std::string对象将在函数被调用时创建并在函数返回时或不久之后销毁,因此任何保存的c_str()指针都将变为悬空。

If the function accepts const std::string& and the argument has type std::string , however, no new object is created when the function is called.但是,如果函数接受const std::string&并且参数的类型为std::string ,则在调用函数时不会创建新对象。 The reference refers to the existing object.引用是指现有对象。 The c_str() pointer will remain valid until the original std::string object is destroyed. c_str()指针将保持有效,直到原始std::string对象被销毁。

A char * isn't an object, it's a pointer to characters that exist in some other context. char *不是对象,它是指向存在于其他上下文中的字符的指针。 If you assign such a pointer to a temporary variable, or data contained within a temporary variable, it will be invalid when the temporary is destroyed.如果将这样的指针分配给临时变量或临时变量中包含的数据,则在销毁临时变量时它将无效。 Using it after that point produces undefined behavior.在那之后使用它会产生未定义的行为。

When you have member variables of std::string , a copy is made at the time of assignment so it doesn't matter if the temporary is destroyed or not.当您拥有std::string成员变量时,会在赋值时进行复制,因此临时对象是否被销毁并不重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当字符串文字作为const字符串传递给函数时会发生什么? - What happens when a string literal passed as const string& to a function? 从C ++的构造函数中向成员const char *变量分配字符串文字时会发生什么? - What happens when assigning a string literal to a member const char* variable from within a constructor in C++? 当作为参数传递给C ++中的函数时,const string&str和string const&str和有什么区别? - What is the difference between const string & str and string const & str when passed as an argument to a function in c++ c ++传递字符串文字而不是const std :: string&? - c++ passing a string literal instead of a const std::string&? 当std :: string对象传递给函数时,字符串数据会发生什么变化? - What happens to the string data when std::string objects are passed to functions? C ++:构造函数仅接受字符串文字 - C++: Constructor accepting only a string literal 在C ++中使用&#39;+&#39;运算符将字符附加到字符串文字时会发生什么? - What exactly happens when a character is appended to a string literal with the '+' operator in C++? 将值传递给 C++ 中的运算符重载器 function 时会发生什么? - What happens when value is passed to operator overloader function in C++? 为什么在分配给 const std::string 时会复制字符串文字? - Why is a string literal copied when assigning to a const std::string? c ++何时返回const char *而不是std:string - c++ when to return a const char* instead of a std:string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM