下面这段代码会输出什么?
[cpp] view plaincopy
- const char* p = string("hello temprary string").c_str();
- cout << p;
下面这段代码运行之后会怎样?
[cpp] view plaincopy
- #include <vector>
- class Foo
- {
- public:
- Foo()
- {
- _p = new char[32];
- }
- ~Foo()
- {
- delete _p;
- }
- private:
- char* _p;
- };
- int main()
- {
- std::vector<Foo> cont;
- cont.push_back(Foo());
- return 0;
- }
第一个会输出奇怪的字符串,第二个会崩溃。
Why?这是临时对象提前销毁造成的。
临时对象会在什么情况下被创建,msdn上介绍有以下几种情况:
- To initialize a const reference with an initializer of a type different from that of the underlying type of the reference being initialized.
- To store the return value of a function that returns a user-defined type. These temporaries are created only if your program does not copy the return value to an object. For example:
UDT Func1(); // Declare a function that returns a user-defined // type. ... Func1(); // Call Func1, but discard return value. // A temporary object is created to store the return // value.
Because the return value is not copied to another object, a temporary object is created. A more common case where temporaries are created is during the evaluation of an expression where overloaded operator functions must be called. These overloaded operator functions return a user-defined type that often is not copied to another object.
Consider the expression ComplexResult = Complex1 + Complex2 + Complex3. The expression Complex1 + Complex2 is evaluated, and the result is stored in a temporary object. Next, the expression temporary + Complex3 is evaluated, and the result is copied to ComplexResult(assuming the assignment operator is not overloaded).
- To store the result of a cast to a user-defined type. When an object of a given type is explicitly converted to a user-defined type, that new object is constructed as a temporary object.
临时对象何时被销毁呢,还是看msdn的介绍:
Temporary objects have a lifetime that is defined by their point of creation and the point at which they are destroyed. Any expression that creates more than one temporary object eventually destroys them in the reverse order in which they were created. The points at which destruction occurs are shown in the following table.
Destruction Points for Temporary Objects
Reason Temporary Created |
Destruction Point |
---|---|
Result of expression evaluation |
All temporaries created as a result of expression evaluation are destroyed at the end of the expression statement (that is, at the semicolon), or at the end of the controlling expressions for for, if, while, do, and switch statements. |
Initializingconstreferences |
If an initializer is not an l-value of the same type as the reference being initialized, a temporary of the underlying object type is created and initialized with the initialization expression. This temporary object is destroyed immediately after the reference object to which it is bound is destroyed. |
注意第一条:由于表达式的计算产生的临时对象会在表达式计算完成(遇到;号)之后被销毁。
所以:
第一个问题中,p在第一行代码之后指向了一被销毁的内存。
第二个问题中,Foo在push_back的那行代码之后被销毁,_p被delete。而vector析构的时候会析构每个元素,_p又被delete,崩溃!
编译器默认的operator=只是赋值每一个字段。要解决第二个问题,可以在operator=中对_p申请另外的内存再拷贝。
关于临时对象的析构造成的问题还可以举出很多例子。掌握了它析构的时机才能很好的避免类似错误。
http://blog.csdn.net/passion_wu128/article/details/38959465