C++编程注意事项——构造函数

C++ 编程注意事项 —— 构造函数

摘要

构造函数使用explicit阻止隐式类型转换
区分拷贝构造函数和赋值运算符的不同
使用引用传递,避免值传递

构造函数

对于自定义的类型,使用explicit阻止执行隐式类型初始化

对于用户自定义的类型,初始化由构造函数执行。将构造函数声明为explicit可以阻止隐式类型转换。被声明为explicit的构造函数通常比non-explicit的构造函数更好,除非有充分的理由,否则所有的构造函数都应该声明为explicit

在显式类型转换使得程序员真的知道自己在做什么,清楚的知道调用了哪个构造函数,如果使用隐式构造函数,程序员可能并不清楚发生了类型转换,即使知道发生了类型转换,在找出实际执行构造函数执行的类型转换也需要花费一定的时间,而这很可能导致发生与预期不符的行为。

拷贝构造函数与赋值运算符

拷贝构造函数用来通过一个已有的同类型对象初始化一个新的对象
赋值运算符则是从另一个同类型对象中拷贝其值到本身
两者最大的区别在于,拷贝构造函数会创建一个新的对象,而赋值运算符并没有创建新的对象。
通过判断是否有新的对象被创建,可以区分调用哪个函数

class A{
    public :
        A();                            //默认构造函数
        A(const A& a);                  //拷贝构造函数
        A& operator=(const A& a);       //赋值运算符
};

A a1;               //调用默认构造函数
A a2(a1);           //调用拷贝构造函数
a1 = a2;            //调用赋值运算符, 没有新的对象创建
A a3 = a1;          //调用拷贝构造函数,新的对象a3被创建

可以通过在构造函数中输出信息来跟踪函数的调用情况:

class TestA{
    public:
        TestA();
        TestA(const TestA& a);
        TestA& operator=(const TestA& a);
};

TestA::TestA(){
    cout << "run default construct;" << endl;
}

TestA::TestA(const TestA& a){
    cout << "run copy construct;" << endl;
}

TestA& TestA::operator=(const TestA& a){
    cout << "run '=';" << endl;
    return *this;
}

int main(int, char**) {
    TestA a1;
    TestA a2(a1);
    a1 = a2;
    TestA a3 = a1;

    return 0;
}

运行结果:

在这里插入图片描述

当以值传递的方式传递参数时,通过调用拷贝构造函数创建一个新的对象,因此拷贝构造函数被调用是一个很重要的函数。同时,在进行参数传递时也应该优先使用引用传递,避免创建新的对象。

posted @   木章永想要平静的生活  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示