0

部分答案在这里给出

class foo1
{
private:
        int i;
public:
        foo1()  
        {
           i=2;
        }
        int geti(){
                return i;
        }
};

class foo2
{
private:
        int j;
public:
        explicit foo2(foo1& obj1) //This ctor doesn't have `const` intentionally as i wanted to understand the behavior.

        {
                cout<<"\nctor of foo2  invoked";
                j=obj1.geti();
        }
};

    foo1 obj1;
    foo2 obj2(obj1); //THIS WORKS

    foo2 obj22=obj1; //THIS DOESN'T WORK

当钥匙explicit被移除时,它们都可以工作。

以下解释对于复制初始化 ( foo2 obj22=obj1) 是否正确:

首先编译器使用构造函数创建一个临时对象: foo2(foo1& other) {} 然后它尝试在复制构造函数中使用这个临时对象: foo2(foo2& other) {} 但它可能不会将临时对象绑定到非常量引用并发出错误。当您使用等号时,就会使用所谓的复制初始化。

如果是,那么foo2(foo1& other) {}在更进一步之前不应该禁止它本身,因为临时不能绑定到非 const 引用?

抱歉,这个问题很长,我的困惑基本上是在存在/不存在显式关键字(带/不带 const)的情况下直接初始化和复制初始化的差异行为

4

1 回答 1

1

以下解释对于复制初始化是否正确

它不是。您省略了复制 c'tor 的定义foo2。这意味着编译器会自动为您合成一个。合成版本将占用const foo2&. 所以问题在于将临时对象绑定foo2到非常量引用。

事实上,复制初始化不再创建临时对象,甚至不必表现得好像临时对象存在一样。相反,初始化的形式只是将explicit关键字考虑在内。

这两个

foo2 obj2(obj1); 
foo2 obj22=obj1; 

执行相同的重载决议,它只能选择相同的 c'tor ( foo2(foo1& obj1))。它应该选择这个 c'tor,因为您为参数传递了一个非常量左值。

区别?允许直接初始化使用显式 c'tor。虽然复制初始化没有。因此,您的显式 c'tor 不是候选人,并且重载决议失败。

于 2020-02-02T08:56:30.557 回答