首页 > 试题广场 >

下面程序运行时的输出结果是?

[单选题]
#include<iostream>
using namespace std;
class MyClass
{
public:
    MyClass(int i = 0)
    {
        cout << i;
    }
    MyClass(const MyClass &x)
    {
        cout << 2;
    }
    MyClass &operator=(const MyClass &x)
    {
        cout << 3;
        return *this;
    }
    ~MyClass()
    {
        cout << 4;
    }
};
int main()
{
    MyClass obj1(1), obj2(2);
    MyClass obj3 = obj1;
    return 0;
}


运行时的输出结果是()
  • 11214444
  • 11314444
  • 122444
  • 123444
推荐
C D 辨析:

关键是区分 浅/深拷贝操作 和 赋值操作:
没有重载=之前:
A a ;
A b;
a = b;
这里是赋值操作。
A a;
A b = a; 
这里是浅拷贝操作。

重载 = 之后:
A a ;
A b;
a = b;
这里是深拷贝操作(当然这道题直接返回了,通常我们重载赋值运算符进行深拷贝操作)。
A a;
A b = a; 
这里还是浅拷贝操作。

所以 MyClass obj3 = obj1; 调用的是拷贝构造函数。

如果写成 MyClass obj3; obj3 = obj1; 输出的结果就是 1203444




编辑于 2016-02-23 17:46:59 回复(41)
C MyClass obj3 = obj1; 
obj3还不存在,所以调用拷贝构造函数输出2,
如果obj3存在,obj3=obj,则调用复制运算符重载函数,输出3 

编辑于 2016-02-23 17:46:59 回复(22)
构造函数的 使用场景: 比如有一个 Test 类
1. 括号法     Test t1(1,2);  有参
2. 等号法   Test t2 = (3,4)  
3. 直接调用   Test t3 = Test( 3,4 )

理解copy构造函数的应用场景: 是用一个对象去初始化另一个对象, 赋值操作不会调用copy构造函数, 
copy构造函数的使用方式一般有 四种:
1.  Test t2 = t1;     用t1来初始化 t2
2.  Test  t2(t1);       用 t1对象 来初始化 t2对象
3.  实参去初始化形参,会调用copy构造函数
4. 函数返回一个元素, 函数的返回值是一个元素(复杂类型的),返回的是一个新的匿名对象(所以会调用匿名对象类的copy构造函数)
Test g() {
    Test  A(1, 2);
    return A;
}
Test t =  g();   

发表于 2018-05-31 22:57:09 回复(0)
        一个对象的诞生首先必须经历构造过程,这也是构造函数存在的意义,而=运算符本身并不具有代替构造函数的作用,在题目中由于obj1、obj2、obj3都是首次出现的对象,因此必须经历构造函数,因此,即使obj3使用了=运算符,但是仍然必须要执行构造函数,此时的=也会被理解成调用了复制构造函数。
       拷贝构造函数的格式为:类名(const 类名& 对象名);//拷贝构造函数的原型,参数是常量对象的引用。由于拷贝构造函数的目的是成员复制,不应修改原对象,所以 建议使用const关键字
编辑于 2017-06-04 17:22:24 回复(0)
谁能给解释下两段程序操作符重载时的区别?
发表于 2017-02-23 18:28:51 回复(7)
隐式拷贝,在explicit声明下不可 =; 实际为obj3(obj1)。
发表于 2015-06-16 10:39:38 回复(0)
拷贝构造函数发生在对象还没有创建,需要创建时,如obj3;赋值操作符重载仅发生在对象已经执行过构造函数,即已经创建的情况下

前两个对象构造时分别输出1,2
第三个对象是这样构造的MyClass obj3 = obj1,之前没有执行过构造函数创建对象,所以这里会调用拷贝构造函数,输出2
然后三个对象依次析构,输出444
所以最终输出122444

发表于 2015-08-06 15:25:06 回复(3)
答案:C 
解释:
首先程序中存在三个MyClass对象。
前两个对象构造时分别输出1,2
第三个对象是这样构造的MyClass obj3 = obj1;这里会调用拷贝构造函数,输出2
然后三个对象依次析构,输出444
所以最终输出122444
编辑于 2015-12-09 18:13:53 回复(9)


class MyClass  
{
public:
    MyClass(int i=0)
    {
        cout<<1;
    } 
    //定义带一个默认参数的构造函数;
    
    MyClass(const MyClass&x)
    {
        cout<<2;
    }
    //这是复制构造函数,当使用复制初始化对象的时候,会调用这个构造函数来初始化对象;  

    MyClass&operator=(const MyClass&x)
    {
        cout<<3;return*this;
    } 
    //这是重载的赋值操作符,当程序中出现对象赋值(就是使用=)的时候,会调用这个函数; 
    
    ~MyClass()
    {
        cout<<4;
    }        
    //这是析构函数,当对象消失时会调用这个函数; 
};  
int main()  
{  
        //把下面的三个语句分开写,方便解释  
        MyClass obj1(1);   
        //调用构造函数MyClass(int i=0)初始化对象obj1,这个函数输出的是1,因此,程序输出1;  
        
        MyClass obj2(2);    
        //同上,调用MyClass(int i=0)初始化对象obj2,输出1;  
        
        MyClass obj3(obj1); 
        //使用obj1对象来初始化obj3对象,属于复制初始化的情形,会调用复制构造函数MyClass(const MyClass&x),因此会输出2;  
        
        MyClass obj4(3); obj4 = obj1;
        //调用MyClass(int i=0)初始化对象obj4,输出1;obj4 = obj1 重载的赋值操作符,当程序中出现=的时候,会调用这个函数,因此会输出3
        return 0;  
}//因为创建了4个对象:obj1、obj2、obj3、obj4,在这里4个对象都会消失,因此,会调用四次析构函数,因此,会输出4次4

编辑于 2018-06-11 17:14:11 回复(4)
1.调用obj1的构造函数MyClass(int i = 0)输出1;
2.调用obj2的构造函数MyClass(int i = 0)输出2;
3.调用obj3的复制构造函数MyClass(const MyClass &x)输出2;
4.main函数返回时分别调用obj3、obj2、obj1的析构函数输出444;

选C
发表于 2015-01-20 14:39:06 回复(0)
一个对象的诞生首先必须经历构造过程,这也是构造函数存在的意义,而=运算符本身并不具有代替构造函数的作用,在题目中由于obj1、obj2、obj3都是首次出现的对象,因此必须经历构造函数,因此,即使obj3使用了=运算符,但是仍然必须要执行构造函数,此时的=也会被理解成调用了复制构造函数。OVER
发表于 2017-01-18 16:22:49 回复(0)
若main函数中改成:
    MyClass obj1(1), obj2(2);
    MyClass obj3;
    obj3 = obj1;
最后执行的结果为:1203444
也就是说:拷贝构造函数发生在对象还没有创建;赋值操作符重载仅发生在对象已经创建的情况下。

发表于 2015-08-05 21:48:04 回复(0)
调用的是拷贝构造函数还是赋值运算符,主要是看是否有新的对象实例产生。
如果产生了新的对象实例,那调用的就是拷贝构造函数;
如果没有,那就是对已有的对象赋值,调用的是赋值运算符

调用拷贝构造函数主要有以下场景:

  • 对象作为函数的参数,以值传递的方式传给函数。
  • 对象作为函数的返回值,以值的方式从函数返回
  • 使用一个对象给另一个对象初始化
发表于 2018-08-10 08:26:38 回复(0)
拷贝构造函数被调用3情况:
                                          1,类对象初始化该类另一对象时;(注意是初始化,不是赋值。本题就是该情况)
                                          2,形参为类对象的函数被调用时;
                                          3,返回值为类对象的函数执行完成返回调用者时。
发表于 2017-05-10 09:45:59 回复(0)
copy constructor,是通过一个已有对象构造出一个产新的对象. 
assign operator ,是将一个已经存在对象的值赋值于另一个已经存在的对象.
发表于 2016-04-25 22:46:26 回复(1)
    MyClass obj3;
     obj3 = obj1;
如果是这种情况,则先会先创建obj3,之后再调用赋值构造函数(打印3)。
需要注意一点,当用户定义了有参构造函数后,C++编译器不再提供默认无参构造函数。
这里创建的有参构造函数有一个默认参数0,所以创建obj3的时候不需要传参也可以调用这个有参构造函数(打印默认参数0),如果这个有参构造函数没有默认参数0,则按照MyClass obj3;这种方式创建对象会导致编译失败,因为没有无参构造函数。

        
发表于 2021-06-02 17:17:21 回复(0)
这道题注意MyClass obj3 = obj1和 MyClass obj3,obj3=obj1的区别。
第一个会调用拷贝构造函数
第二个会调用赋值函数
发表于 2015-12-18 17:21:53 回复(0)
MyClass obj3 = obj1;调用的是拷贝构造函数,
如果是obj3 = obj1;调用的就是赋值运算符了。
发表于 2015-04-18 22:29:45 回复(1)
C
obj1和obj2显然调用构造函数打印传入参数
obj3调用拷贝构造函数打印2
然后是三个析构函数打印4
发表于 2015-03-10 11:40:15 回复(0)
若main函数中改成: MyClass obj1(1), obj2(2); MyClass obj3; obj3 = obj1; 最后执行的结果为:1203444 也就是说:拷贝构造函数发生在对象还没有创建;赋值操作符重载仅发生在对象已经创建的情况下。
发表于 2023-05-31 16:03:25 回复(0)
编辑于 2022-03-20 20:04:18 回复(0)