首页 > 试题广场 >

不考虑任何编译器优化(如:NRVO),下述代码的第10行会发

[单选题]
不考虑任何编译器优化(如:NRVO),下述代码的第10行会发生
#include <stdio.h>
class B{
};
B func(const B& rhs){
  return rhs;
}
int main(int argc, char **argv){
  B b1, b2;
  b2 = func(b1);  //10
}
  • 一次默认构造函数,一次拷贝构造函数,一次析构函数,一次(拷贝赋值运算符)operator=
  • 二次拷贝构造函数,一次析构函数
  • 一次(拷贝赋值运算符)operator=,一次析构函数
  • 一次拷贝构造函数,一次析构函数,一次(拷贝赋值运算符)operator=
推荐
D
b2=func(b1);//10
一次拷贝构造函数发生在func函数调用完成,返回B类型的对象时,因为返回的不是引用类型,所以会生成一个对象,
不妨称为TEMP,将返回的对象通过拷贝构造函数复制给TEMP,然后,返回值所对应的对象会被析构。如果返回值是引用类型,
则不会调用拷贝构造函数。

赋值运算符在func函数执行完成后,将上面提到的TEMP,通过赋值运算符赋值给b2,值得注意的是赋值运算符重载函数如果不自己定义,
程序会认为是调用缺省的赋值运算符重载函数。
编辑于 2015-12-10 13:26:31 回复(9)
zray4u说得不完全对
大家可以去自己调试一下 答案是D 但是次序并不是 
一次拷贝构造函数,一次析构函数,一次(拷贝赋值运算符)operator=
而是
一次拷贝构造函数,一次(拷贝赋值运算符)operator= ,一次析构函数

1.一次拷贝构造函数发生在func函数调用完成,返回B类型的对象时,因为返回的不是引用类型,所以会生成一个对象,不妨称为TEMP,将返回的对象通过拷贝构造函数复制给TEMP,由于拷贝构造函数的参数是const B&,rhs并不会在函数结束时候被析构,这时并不调用析构函数;
2.赋值运算符在func函数执行完成后,将上面提到的TEMP,通过赋值运算符赋值给b2;
3.这句表达式的最后将临时对象TEMP进行析构;

可以试一试将B func(constB& rhs) 改为B func(constB rhs),rhs才会被析构;
发表于 2016-07-23 15:43:33 回复(9)
#include <stdio.h>
 
classB
{
public:
    B(){
        printf("B constructor.\n");
    }
    ~B(){
        printf("B destructor.\n");
    }
    B(constB& other)
    {
        printf("B copy constructor.\n");
    }
        B& operator =(B& rhs)
    {
        printf("operator = .\n");
        returnrhs;
    }
 
};
 
B func(constB& rhs){
 
    printf("function func.\n");
    returnrhs;
}
 
intmain(intargc,char**argv)
{
  B b1,b2;
  {
  b2=func(b1);
  }
 
  getchar();
  return0;
}

发表于 2016-08-31 10:45:03 回复(3)
func参数不会拷贝因为是引用,返回值会产生一个新对象,函数返回发生一次拷贝,然后赋值给b2,最后析构b1
发表于 2021-02-20 12:10:58 回复(3)
感觉大多数不是纠结析构的顺序问题,而是返回的时候为什么会调用一次拷贝构造和一次赋值符。 func在返回的时候执行的操作类似于: B temp=rhs;//拷贝构造 b2=temp;//赋值符= //赋值符调用完后再析构temp
发表于 2016-11-12 12:47:48 回复(0)
b1作为形参传递调用一次 复制构造函数,fun的返回值给b2用一次赋值构造函数,fun函数结束执行一次析构函数
发表于 2015-12-03 17:22:45 回复(1)
答案是D
            既然是这一行b2=func(b1);
       那么就会发生一次拷贝构造函数,一次析构函数,一次(拷贝赋值运算符)operator= ,会发生一次拷贝构造函数,
在第5的地方, 一次(拷贝赋值运算符)operator=是在b2"=" func(b1)发生的,如果此时是 b2=func(b1);那么就是二次拷贝构造函数
 最后还会发送析构函数,所以答案为D
编辑于 2015-12-10 13:26:08 回复(3)
#include <stdio.h>
class B{
};
B func(const B& rhs){
  return rhs;
}
int main(int argc, char **argv){
  B b1, b2;
  b2 = func(b1);  //10
}
第十行所执行的动作分析:
1、func(b1);b1引用传递给rhs,不会发生什么。
2、return rhs;返回值是以B类型的值的方式返回,即B temp = rhs;temp调用拷贝构造函数。
3、b2 = func(b1);也就是b2 = temp;此时b2调用operator=赋值操作符函数
4、当b2 = func(b1);执行完后,temp调用析构释放

发表于 2023-04-29 23:13:31 回复(0)
拷贝构造函数调用时机:http://blog.csdn.net/lwbeyond/article/details/6202256
class B  
{  
 
public:  
 //构造函数  
 B()  
 {   
  cout<<"B()"<<endl;  
 }  
  
 //拷贝构造  
 B(const B& b)  
 {  
  cout<<"&B()"<<endl;  
 }  
   
 //析构函数  
 ~B()  
 {  
  cout<< "~B()"<<endl;  
 }  
  
};  
  
B func(const B &res)  
{  
 cout<<"func()"<<endl;  
 return res;
}  
   
int main() {
	B b1,b2;  
	b2=func(b1);  
	system("pause");
	return 0;
}
最终结果:B()  B()  func()  &B()  ~B()
若将B func(const B &res)改为B func(const B res), 则最终结果为:B()  B() &B() func() &B() ~B()  ~B()
编辑于 2017-04-19 14:23:22 回复(0)
fun()返回参数时会生成一个匿名对象,会调用拷贝构造函数,b2在之前已经调用构造函数,所以匿名对象会浅拷贝operator=,完成后析构匿名对象;如果是这样的  B b2=func(b1),直接会调用匿名对象初始化b2,就不会调用浅拷贝 operator=
发表于 2016-06-20 20:29:48 回复(0)
怎么区分是拷贝构造函数还是赋值运算符重载?
“=”只有在赋值时才调用赋值运算符,当在声明变量时,B b3=b1和B b4(b3)调用的函数是一样的,均为拷贝构造函数。
在10行,fun函数中生成了一个临时变量,用了一次拷贝构造函数,函数结束调用析构函数,
在函数外的“=”是赋值运算符重载
发表于 2016-03-04 10:44:35 回复(1)

由于返回值不是引用类型,因此在函数调用完成后会调用一次拷贝构造函数来生成临时对象返回,返回后调用析构函数销毁临时对象。然后在将临时对象赋值给b2时会调用一次赋值运算符重载函数。

发表于 2023-11-30 19:57:25 回复(0)
搞不懂搞不懂,想练个C整这麽多C++。。。
发表于 2023-10-04 18:57:56 回复(0)
临时对象调用析构函数
发表于 2023-09-15 21:18:07 回复(0)
函数返回一个对象在栈区,相当于在栈区开辟一个临时对象接收函数返回的匿名对象,这个新开辟匿名对象接收函数返回的对象就会调用拷贝构造;
之后用b2接收这个匿名对象,因为b2已经不是新的对象了(已经被创建过),所以不会调用拷贝构造,而是会调用重载运算符“=”;
最后当这个语句结束,匿名对象的空间被释放,调用析构函数
发表于 2023-05-24 19:27:37 回复(0)
发表于 2022-06-27 09:55:21 回复(0)
解析和leetcode的差距不小
发表于 2022-02-07 13:00:34 回复(0)
第五行传递的是对象的引用,而不是对象,所以不调用拷贝构造函数。 调用拷贝构造函数的三种情况 1.用类的对象去初始化类新建立的对象 2.对象的形参是类的对象,将对象作为实参去初始化 3.函数返回值是类的对象,在堆中建立一个临时对象,将函数返回的对象复制给该临时对象。
发表于 2021-08-28 11:29:09 回复(0)
c++的面向对象真的不如java舒服,看着就恶心。
发表于 2021-07-15 13:29:10 回复(0)
看了解析依然看不懂😭😭😭
发表于 2021-04-22 10:57:09 回复(0)
func(b2)可以看成匿名对象,执行结束后系统会立即回收掉匿名对象,这时候析构
发表于 2021-03-29 23:40:21 回复(0)