请教两道C++拷贝构造函数vs重载赋值操作符=的面试题

首先请教一下概念:比如现在定义了一个class叫Example,然后main()函数里先声明了Example A; 再Example B=A或者Example B(A)。

这里,“Example B=A”自然属于重载赋值操作符=,那么“Example B(A)”是否也属于重载赋值操作符=呢?看到网上有句话叫“当需要拷贝构造函数时,重载赋值操作符也是需要的;反之亦然。”——这个说法是否正确呢?

面试题1:

class Sc

    {

    public:

        int x;

    public:

        Sc(int xx): x(xx) {}

        Sc(const Sc&a) {x=a.x; x++;}

        void operator = (const Sc &a1) {x=a1.x; x--;}

    };

int main()

    {

    Sc a(4);

    Sc b=a;

    cout << b.x << endl;

    return 0;

    }

请问运行之后为什么b.x是5呢?

面试题2:

class String

    {

    public:

        explicit String(char ch, int n=1) {}

        String(const char *p) {}

    private:

        void operator = (const char*) {}

    };

int main()

    {

    String x="aaa";

    return 0;

    }

面试官问:“这段程序显然有问题。那么问题出在哪里呢?explicit,还是constructor,还是operator=呢?”

恳请指点。谢谢大家!


SMILET
浏览 1168回答 2
2回答

宝慕林4294392

“Example B=A”自然属于重载赋值操作符=,那么“Example B(A)”是否也属于重载赋值操作符=呢?这里 Example B = A 不是重载赋值,而是隐含的调用了 Example(Example& ) 这个构造函数,如果用户没有定义 就是用合成的函数 bitcopy过去的。同理 Example B(A);对于这个比较现代的编译器应该都是这么实现的。如果你单独写Example B;&nbsp;这是一个声明,但是如果有可用的构造函数(包括是编译器合成的) 那么会自动调用初始化。认为 Example B = A;就存在一次赋值,大概是 Example B = A; 早期会被解释成Example B;B = A;&nbsp;但是从现代编译器的实现上是不正确的,现代编译器没那么傻。当需要拷贝构造函数时,重载赋值操作符也是需要的;反之亦然.可否说明出处。Example(Example& )就是拷贝构造函数,这句话的意思是为了兼容上面不同的编译器实现?也就是Example B = A 会出现一次赋值的这种实现。面试题一:同样的问题,你理解了上面的就理解了,这道题面试题二:应为赋值重载被干掉了,所以可能不兼容上述的多一次赋值的那种编译器实现?感觉你的这个题目可能有点年代。所以你是在面试哪一家。。

偶然的你

Example B(A) 是调用拷贝构造函数.Sc b=a;&nbsp;调用拷贝构造函数, 所以&nbsp;b.x&nbsp;初始化为4, 在,&nbsp;x++&nbsp;得到 5.没有问题, 会使用默认合成的拷贝构造函数.&nbsp;String x="aaa";执行拷贝初始化, 而且拷贝构造函数的参数是const String &. 所以会根据构造函数String(const char *p) {}转换为对应的String对象,在进行拷贝初始化.你可以这样测试:String(const&nbsp;char&nbsp;*p)&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"run&nbsp;String(const&nbsp;char&nbsp;*p)"&nbsp;<<&nbsp;std::endl;&nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP