赋值运算符未调用参数化构造函数,而代码中存在复制构造函数

Assignment operator is not calling parameterized constructor while copy constructor present in code

提问人:Parag Jain 提问时间:10/5/2021 最后编辑:Parag Jain 更新时间:10/6/2021 访问量:156

问:

案例一:当我使用赋值运算符创建类的对象时,如果代码中没有复制构造函数,它会调用参数化构造函数。

下面的代码没有复制构造函数:

class Test{
    public:
    int a;
    Test(int a){
        this->a = a;
    }
};
int main(){
    Test x = 6;
    cout<<x.a;
    return 0;
}

案例二:但是,如果类中存在复制构造函数,那么如果我在声明类对象时使用赋值运算符,则会出现错误。

错误:无法将类型为“Test&”的非常量左值引用绑定到类型为“Test”的右值

下面的代码是带有复制构造函数的

class Test{
    public:
    int a;
    Test(int a){
        this->a = a;
    }
    Test(Test &b){
       this->a = b.a;
    }

};
int main(){
    Test x = 6;
    cout<<x.a;
    return 0;
}

我的问题是复制构造函数的存在如何导致结果最终出错?由于存在复制构造函数,当我将参数分配给类的对象时,我的程序也应该调用 Parameterize 构造函数。

C++ 对象 OOP 构造函数 复制构造函数

评论

2赞 molbdnilo 10/5/2021
in 初始化不是赋值运算符。初始化和赋值之间的区别在 C++ 中非常重要。=
0赞 Aconcagua 10/5/2021
题外话,但您应该习惯于使用构造函数的初始化器列表(不要与 ): (或者最好为参数单独命名: .特别是当涉及复杂类型时,这更喜欢按值直接初始化,而不是默认初始化 + 赋值。除此之外,有些成员只能以这种方式初始化(常量成员、引用、非默认可构造类型等)。std::initializer_listTest(int a) : a(a) {}Test(int b) : a(b) {}
0赞 molbdnilo 10/5/2021
问题在于您自己的复制构造函数采用非常量引用。您会看到相同的错误void f(int&){} int main() { f(6); }
1赞 Aconcagua 10/5/2021
顺便说一句,你的“复制”构造函数是完全有缺陷的:首先它应该接受一个对象,它不应该尝试复制(未初始化! 进入另一个对象,但反过来。因此,与初始化器列表(请参阅我之前的评论)一起,它应该看起来像:constthisTest(Test const& b) : a(b.a) {}

答:

4赞 sagi 10/5/2021 #1

我认为:

Test(Test &b){
   this->a = b.a;
}

实际上应该是这样的:

Test(Test const &b){
   this->a = b.a;
}

复制构造函数应该获得常量引用,并且它们应该将参数内容复制到当前对象内容中,而不是相反。

0赞 matt 10/6/2021 #2

推荐这个问题,因为解释 const 和非 const 变量。 这是因为解释这个错误:

错误:无法将类型为“Test&”的非常量左值引用绑定到 “Test”类型的右值

C++ 对此表示不满,因为它是初始化:

int main(){
    Test x=6;//initialization "const Test& obj = 6" OK
}

但是 C++ 不允许这样做(非常量值):

int main(){
    Test x=6;//initialization "Test& obj = 6" Not Ok!
}