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<char> m_buffer;
};
Run Code Online (Sandbox Code Playgroud)
以下是您将如何使用它:
// 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);
Run Code Online (Sandbox Code Playgroud)
什么时候会调用临时StringBuffer对象的析构函数?是吗:
我知道C++保证本地临时变量只要有引用就有效 - 当引用成员变量时,它是否适用于父对象?
谢谢.
当创建a的新实例MyClass作为函数的参数时,如下所示:
class MyClass
{
MyClass(int a);
};
myFunction(MyClass(42));
Run Code Online (Sandbox Code Playgroud)
该标准是否使得任何被授权者都能获得析构函数的时间安排?
具体来说,我可以假设在调用之后的下一个语句之前调用它myFunction()吗?
以前的情况是预增量是首选的,因为类上的重载后增量需要返回表示增量前对象状态的临时副本.
似乎这不再是一个严重的问题(只要内联就位),因为我的旧C++编译器(GCC 4.4.7)似乎将以下两个函数优化为相同的代码:
class Int {
//...
public:
Int (int x = 0);
Int & operator ++ ();
Int operator ++ (int) {
Int x(*this);
++*this;
return x;
}
};
Int & test_pre (Int &a) {
++a;
return a;
}
Int & test_post (Int &a) {
a++;
return a;
}
Run Code Online (Sandbox Code Playgroud)
两个函数的结果汇编是:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movq %rdi, %rbx
call _ZN3IntppEv
movq %rbx, %rax
popq %rbx
.cfi_def_cfa_offset 8
ret
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
然而,如果没有任何内联,那么优先选择预增量到后增量似乎仍然有好处,因为它
test_post被强制调用operator++(int). …
可能重复:
C++:临时参数的生命周期?
据说临时变量作为评估完整表达式的最后一步被破坏,例如
bar( foo().c_str() );
Run Code Online (Sandbox Code Playgroud)
临时指针一直存在,直到bar返回,但是为什么
baz( bar( foo().c_str() ) );
Run Code Online (Sandbox Code Playgroud)
是否它仍然存在直到bar返回,或者baz返回意味着完全表达结束在这里,编译器我检查了baz返回后的destruct对象,但我可以依赖它吗?
为什么以下代码打印"xxY"?局部变量不应该存在于整个函数的范围内吗?我可以使用这种行为,或者在将来的C++标准中会改变这种行为吗?
我认为根据C++标准3.3.2" 块中声明的名称是该块的本地名称.它的潜在范围从其声明点开始,并在其声明区域的末尾结束. "
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass( int ) { cout << "x" << endl; };
~MyClass() { cout << "x" << endl; };
};
int main(int argc,char* argv[])
{
MyClass (12345);
// changing it to the following will change the behavior
//MyClass m(12345);
cout << "Y" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
基于响应,我可以假设这MyClass(12345);是表达式(和范围).这是有道理的.所以我希望以下代码将始终打印"xYx":
MyClass (12345), cout << "Y" << endl;
Run Code Online (Sandbox Code Playgroud)
并且允许进行这样的替换:
// this much strings with explicit scope
{
boost::scoped_lock lock(my_mutex); …Run Code Online (Sandbox Code Playgroud) 给出以下代码:
#include <iostream>
struct implicit_t
{
implicit_t(int x) :
x_m(x)
{
std::cout << "ctor" << std::endl;
}
~implicit_t()
{
std::cout << "dtor" << std::endl;
}
int x_m;
};
std::ostream& operator<<(std::ostream& s, const implicit_t& x)
{
return s << x.x_m;
}
const implicit_t& f(const implicit_t& x)
{
return x;
}
int main()
{
std::cout << f(42) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
ctor
42
dtor
Run Code Online (Sandbox Code Playgroud)
虽然我知道这是正确的,但我不确定为什么.有没有stdc ++知识的人可以向我解释一下?
以下代码有什么问题?我只是尝试建立一个非常简单的线程安全堆栈,当我运行多个线程同时推送并弹出堆栈时,它有时会报告0xC0000005异常.
#include <stack>
#include <list>
#include <memory>
#include <mutex>
template<class T> class Stack{
typedef stack < shared_ptr<T>, list<shared_ptr<T>>> Stack_;
public:
Stack(){}
Stack(const Stack& other){
lock_guard<mutex>(other.mtx_);
stack_ = other.stack_;
}
void push(shared_ptr<T> value){
lock_guard<mutex>(this->mtx_);
stack_.push(value);
}
shared_ptr<T> pop(){
lock_guard<mutex>(this->mtx_);
if (stack_.empty()) return nullptr;
auto res = stack_.top();
stack_.pop();
return res;
}
private:
mutex mtx_;
Stack_ stack_;
};
Run Code Online (Sandbox Code Playgroud) 这个简单的代码块以一种意想不到的方式运行.
#include <iostream>
using namespace std;
class Node
{
public:
char* data;
Node(char d)
{
data = &d;
}
};
int main()
{
Node NodeA = Node('c');
cout<<*(NodeA.data)<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我期待得到'c'作为输出,但它输出'}'.我觉得它必须与将"数据"指针分配给一个匿名变量'c'有关.
我发现这个问题讨论了类似的问题.
但正如在最高层回答中提到的那样,匿名变量只有在没有被表达式末尾引用它的指针限制时才会被杀死.我认为这不是这里的情况,因为我将指针("数据")绑定到它,但不知怎的,它仍然被杀死.
我想知道导致意外输出的是什么.
在由静态数据字段引起的消费者文件中询问C++ Error链接之后,我为StateConservator的一个实例尝试了两种不同的声明:
StateConservator cs(*pContainer, pDoc->GetConfiguration());
Run Code Online (Sandbox Code Playgroud)
和
StateConservator(*pContainer, pDoc->GetConfiguration());
Run Code Online (Sandbox Code Playgroud)
第一个做了我想要的,它只在范围结束后才传递析构函数.第二个在声明本身的行中传递析构函数.
编译器是否正常运行?如果是正确的行为,在该行中声明匿名变量的方法是什么?
c++ ×9
constructor ×2
destructor ×2
scope ×2
anonymous ×1
lifetime ×1
optimization ×1
raii ×1
temporary ×1