为什么不调用析构函数?
Why destructor is not called?
我写了两个程序来理解复制对象的概念。
第一个:
#include<bits/stdc++.h>
using namespace std;
class myInt
{
int x;
public:
myInt()
{
cout<< "default constructor is called" << endl;
}
myInt(int x)
{
cout<< "constructor is called with initializer" << endl;
this->x = x;
}
~myInt()
{
cout<< "destructor is called" << endl;
}
};
myInt func(myInt ob)
{
return ob;
}
int main()
{
myInt ob1(2);
func(ob1);
}
输出:
constructor is called with initializer
destructor is called
destructor is called
destructor is called
这里的析构函数被调用了3次,也就是说创建了3个对象。一个用于对象 'ob1',一个用于 func() 内部的 'ob',另一个用于从 func() 返回 'ob'。
我的第二个代码:
#include<bits/stdc++.h>
using namespace std;
class myInt
{
int x;
public:
myInt()
{
cout<< "default constructor is called" << endl;
}
myInt(int x)
{
cout<< "constructor is called with initializer" << endl;
this->x = x;
}
~myInt()
{
cout<< "destructor is called" << endl;
}
};
myInt func(myInt ob)
{
return ob;
}
int main()
{
myInt ob1(2);
myInt ob2 = func(ob1);
}
输出:
constructor is called with initializer
destructor is called
destructor is called
destructor is called
这里也创建了 3 个对象作为第一个对象。但是,当我将 func() 返回的对象存储在其中时,不应该再调用一个 'ob2' 的析构函数吗?为什么两种情况下的析构函数调用次数相同?
正如评论中指出的那样,由于复制省略,当它们仅用于初始化另一个对象时,创建临时对象可能会被省略。使用 -fno-elide-constructors
编译您的代码以将其关闭,您将阅读 destructor is called
四次。这里有一个demo.
然而,在 c++17 中情况有所不同。它保证在某些情况下省略副本(prvalue 用作具有相同类型的对象的初始值设定项)。在那里,它不再被视为优化(即 -fno-elide-constructors
在这里没有效果)。看到这个不错的 article or the proposal for details. The following example(从链接文章中窃取)可以用 c++17 很好地编译,因为我们保证没有 copy-/move 构造函数被调用:
struct Foo {
Foo() { std::cout << "Constructed" << std::endl; }
Foo(const Foo &) = delete;
Foo(const Foo &&) = delete;
~Foo() { std::cout << "Destructed" << std::endl; }
};
Foo f() {
return Foo();
}
int main() {
Foo foo = f();
}
我写了两个程序来理解复制对象的概念。 第一个:
#include<bits/stdc++.h>
using namespace std;
class myInt
{
int x;
public:
myInt()
{
cout<< "default constructor is called" << endl;
}
myInt(int x)
{
cout<< "constructor is called with initializer" << endl;
this->x = x;
}
~myInt()
{
cout<< "destructor is called" << endl;
}
};
myInt func(myInt ob)
{
return ob;
}
int main()
{
myInt ob1(2);
func(ob1);
}
输出:
constructor is called with initializer
destructor is called
destructor is called
destructor is called
这里的析构函数被调用了3次,也就是说创建了3个对象。一个用于对象 'ob1',一个用于 func() 内部的 'ob',另一个用于从 func() 返回 'ob'。 我的第二个代码:
#include<bits/stdc++.h>
using namespace std;
class myInt
{
int x;
public:
myInt()
{
cout<< "default constructor is called" << endl;
}
myInt(int x)
{
cout<< "constructor is called with initializer" << endl;
this->x = x;
}
~myInt()
{
cout<< "destructor is called" << endl;
}
};
myInt func(myInt ob)
{
return ob;
}
int main()
{
myInt ob1(2);
myInt ob2 = func(ob1);
}
输出:
constructor is called with initializer
destructor is called
destructor is called
destructor is called
这里也创建了 3 个对象作为第一个对象。但是,当我将 func() 返回的对象存储在其中时,不应该再调用一个 'ob2' 的析构函数吗?为什么两种情况下的析构函数调用次数相同?
正如评论中指出的那样,由于复制省略,当它们仅用于初始化另一个对象时,创建临时对象可能会被省略。使用 -fno-elide-constructors
编译您的代码以将其关闭,您将阅读 destructor is called
四次。这里有一个demo.
然而,在 c++17 中情况有所不同。它保证在某些情况下省略副本(prvalue 用作具有相同类型的对象的初始值设定项)。在那里,它不再被视为优化(即 -fno-elide-constructors
在这里没有效果)。看到这个不错的 article or the proposal for details. The following example(从链接文章中窃取)可以用 c++17 很好地编译,因为我们保证没有 copy-/move 构造函数被调用:
struct Foo {
Foo() { std::cout << "Constructed" << std::endl; }
Foo(const Foo &) = delete;
Foo(const Foo &&) = delete;
~Foo() { std::cout << "Destructed" << std::endl; }
};
Foo f() {
return Foo();
}
int main() {
Foo foo = f();
}