为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

SMILET 2018-07-31 15:21:13
首先请教一下概念:比如现在定义了一个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=呢?”恳请指点。谢谢大家!
查看完整描述

2 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

“Example B=A”自然属于重载赋值操作符=,那么“Example B(A)”是否也属于重载赋值操作符=呢?
这里 Example B = A 不是重载赋值,而是隐含的调用了 Example(Example& ) 这个构造函数,如果用户没有定义 就是用合成的函数 bitcopy过去的。同理 Example B(A);

对于这个比较现代的编译器应该都是这么实现的。如果你单独写
Example B; 
这是一个声明,但是如果有可用的构造函数(包括是编译器合成的) 那么会自动调用初始化。认为 Example B = A;就存在一次赋值,大概是 Example B = A; 早期会被解释成
Example B;
B = A; 
但是从现代编译器的实现上是不正确的,现代编译器没那么傻。

当需要拷贝构造函数时,重载赋值操作符也是需要的;反之亦然.

可否说明出处。Example(Example& )就是拷贝构造函数,这句话的意思是为了兼容上面不同的编译器实现?也就是Example B = A 会出现一次赋值的这种实现。

面试题一:

同样的问题,你理解了上面的就理解了,这道题

面试题二:

应为赋值重载被干掉了,所以可能不兼容上述的多一次赋值的那种编译器实现?

感觉你的这个题目可能有点年代。所以你是在面试哪一家。。


查看完整回答
反对 回复 2018-08-06
?
偶然的你

TA贡献1841条经验 获得超3个赞

  1. Example B(A) 是调用拷贝构造函数.

  2. Sc b=a; 调用拷贝构造函数, 所以 b.x 初始化为4, 在, x++ 得到 5.

  3. 没有问题, 会使用默认合成的拷贝构造函数String x="aaa";执行拷贝初始化, 而且拷贝构造函数的参数是const String &. 所以会根据构造函数String(const char *p) {}转换为对应的String对象,在进行拷贝初始化.
    你可以这样测试:

String(const char *p) { 
    std::cout << "run String(const char *p)" << std::endl; 
}


查看完整回答
反对 回复 2018-08-06
  • 2 回答
  • 0 关注
  • 1118 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信