C++是否为在函数调用中创建但未用作参数的临时变量的生命周期提供保证?这是一个示例类:
class StringBuffer { public: StringBuffer(std::string & str) : m_str(str) { m_buffer.push_back(0); } ~StringBuffer() { m_str = &m_buffer[0]; } char * Size(int maxlength) { m_buffer.resize(maxlength + 1, 0); return &m_buffer[0]; } private: std::string & m_str; std::vectorm_buffer; };
以下是您将如何使用它:
// this is from a crusty old API that can't be changed void GetString(char * str, int maxlength); std::string mystring; GetString(StringBuffer(mystring).Size(MAXLEN), MAXLEN);
什么时候会调用临时StringBuffer对象的析构函数?是吗:
在调用GetString之前?
GetString返回后?
编译器依赖?
我知道C++保证本地临时变量只要有引用就有效 - 当引用成员变量时,它是否适用于父对象?
谢谢.
在完整表达式结束时调用那种临时数的析构函数.这是最外层的表达,不是任何其他表达的一部分.在您的情况下,在函数返回并评估值之后.所以,它会很好用.
事实上,正是使表达模板起作用的原因:它们可以在表达式中保持对那种临时表的引用
e = a + b * c / d
因为每个临时都会持续到表达式
x = y
完全评估.它12.2 Temporary objects
在标准中非常简洁地描述.
litb的回答很准确.临时对象的生命周期(也称为rvalue)与表达式相关联,并且在完整表达式的末尾调用临时对象的析构函数,并且当调用StringBuffer上的析构函数时,m_buffer上的析构函数也将是调用,但不是m_str上的析构函数,因为它是一个引用.
请注意,C++ 0x稍微改变了一些东西,因为它添加了rvalue引用并移动了语义.基本上通过使用rvalue引用参数(用&&表示),我可以将rvalue"移动"到函数中(而不是复制它),并且rvalue的生命周期可以绑定到它移动到的对象,而不是表达式.MSVC团队有一篇非常好的博客文章,详细介绍了这一点,我鼓励大家阅读.
移动右值的教学示例是临时字符串,我将在构造函数中显示赋值.如果我有一个包含字符串成员变量的类MyType,可以在构造函数中使用rvalue初始化它,如下所示:
class MyType{ const std::string m_name; public: MyType(const std::string&& name):m_name(name){}; }
这很好,因为当我使用临时对象声明此类的实例时:
void foo(){ MyType instance("hello"); }
发生的事情是我们避免复制和销毁临时对象,并且"hello"直接放在拥有类实例的成员变量中.如果对象的重量比"字符串"重,则额外的复制和析构函数调用可能很重要.