新手一枚,向各位大佬请教个问题,在vs2019里编译的,运行的时候整个人都蒙了。

qq_46002224 2020-03-19 11:11:06
#include<iostream> using namespace std; class A{ public: A(int n=10){cout<<"默认构造"<<endl;} /*这里如果注释掉了下边的拷贝函数,运行程序的时候他会调用两次析构函数,只调用一次默认构造函数,运行是在vs2019中,加了个断点看着他把自己析构了两次,把下边的注释调结果调用一次构造函数,调用一次析构函数,我把这个在网页上找了个在线的编译器运行了一下,不管注不注释下面的拷贝函数结果都是调用一次构造函数一次析构函数,到这一头雾水,我也没搞懂那个add函数里传的是什么意思,是照着老师出的题写的,写的不是很全,剩了些参数。 */ A(const A& a){cout<<"拷贝"<<endl;} ~A(){cout<<"析构函数"<<endl;} }; void add(A a){} int main() { add(A(10)); return 0; }
...全文
89 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_46002224 2020-03-20
  • 打赏
  • 举报
回复
引用 1 楼 qq_46221910的回复:
应该是实参和形参都调用了析构,而拷贝构造相当于是一个引用,add函数是一个空函数,只是定义了一个A对象的形参
没搞明白拷贝函数那,加上只调用一次析构,不加调了两次,构造函数我加短点一步步走的时候只调了一次,我特意又换了两个编译器,结果一个和vs一样,一个和我说的网页上的一样,这是不是跟编译器有关。
宇来风满楼 2020-03-20
  • 打赏
  • 举报
回复
应该是实参和形参都调用了析构,而拷贝构造相当于是一个引用,add函数是一个空函数,只是定义了一个A对象的形参
qq_46002224 2020-03-20
  • 打赏
  • 举报
回复
引用 4 楼 真相重于对错的回复:
注意我贴的那一段,当你不提供构造函数时,编译器提供的构造函数形式位T(T&) 不是T (const T&) 因为参数是T& 不能直接绑定临时变量所以要发生复制。 而你提供了T(const & T) 会引起复制消除,具体看
https://zh.cppreference.com/w/cpp/language/copy_elision
因为给A加了一个字段B,B具有T(const T&)形式的拷贝构造函数,所以A的隐式拷贝构造将会是A(const A&)形式, 所以,会引起拷贝消除。
有劳你费心了,谢谢。
真相重于对错 2020-03-20
  • 打赏
  • 举报
回复
注意我贴的那一段,当你不提供构造函数时,编译器提供的构造函数形式位T(T&) 不是T (const T&) 因为参数是T& 不能直接绑定临时变量所以要发生复制。 而你提供了T(const & T) 会引起复制消除,具体看
https://zh.cppreference.com/w/cpp/language/copy_elision
因为给A加了一个字段B,B具有T(const T&)形式的拷贝构造函数,所以A的隐式拷贝构造将会是A(const A&)形式, 所以,会引起拷贝消除。
真相重于对错 2020-03-20
  • 打赏
  • 举报
回复
个人认为 ========= 若不对类类型(struct、class 或 union)提供任何用户定义的复制构造函数,则编译器始终会声明一个复制构造函数,作为其类的非 explicit 的 inline public 成员。当以下各项均为真时,这个隐式声明的复制构造函数拥有形式 T::T(const T&): T 的每个直接与虚基类 B 均拥有复制构造函数,其形参为 const B& 或 const volatile B&; T 的每个类类型或类类型数组的非静态数据成员 M 均拥有复制构造函数,其形参为 const M& 或 const volatile M&。 否则,隐式声明的复制构造函数是 T::T(T&)。(注意因为这些规则,隐式声明的复制构造函数不能绑定到 volatile 左值实参)。 ================ 以上摘自cpprefrence 试一下下列代码
class B {
public:
	B(){}
	B(const B& ){}
};
class A {
	B b1;
public:
	A(int n = 10) { cout << "默认构造" << endl; }
	/*这里如果注释掉了下边的拷贝函数,运行程序的时候他会调用两次析构函数,只调用一次默认构造函数,运行是在vs2019中,加了个断点看着他把自己析构了两次,把下边的注释调结果调用一次构造函数,调用一次析构函数,我把这个在网页上找了个在线的编译器运行了一下,不管注不注释下面的拷贝函数结果都是调用一次构造函数一次析构函数,到这一头雾水,我也没搞懂那个add函数里传的是什么意思,是照着老师出的题写的,写的不是很全,剩了些参数。
	*/
	
	~A() {
		cout << this << endl;
		cout << "析构函数" << endl; 
	}
};

void add(A a) {
}

int main()
{
	add(A(10));
	return 0;
}

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧