当前位置:  开发笔记 > 编程语言 > 正文

C++中临时的保证寿命?

如何解决《C++中临时的保证寿命?》经验,为你挑选了2个好方法。

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::vector m_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++保证本地临时变量只要有引用就有效 - 当引用成员变量时,它是否适用于父对象?

谢谢.



1> Johannes Sch..:

在完整表达式结束时调用那种临时数的析构函数.这是最外层的表达,不是任何其他表达的一部分.在您的情况下,在函数返回并评估值之后.所以,它会很好用.

事实上,正是使表达模板起作用的原因:它们可以在表达式中保持对那种临时表的引用

e = a + b * c / d

因为每个临时都会持续到表达式

x = y

完全评估.它12.2 Temporary objects在标准中非常简洁地描述.


我从来没有得到一份标准副本.我应该把它作为优先事项.
@GrimFandango AIUI您的整个`printf`就是完整的表达。因此,`strdup`是不必要的内存泄漏-您可以让它直接打印`c_str()`。

2> Rick..:

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"直接放在拥有类实例的成员变量中.如果对象的重量比"字符串"重,则额外的复制和析构函数调用可能很重要.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有