美文网首页
c++拷贝构造函数

c++拷贝构造函数

作者: arkliu | 来源:发表于2022-11-21 08:36 被阅读0次

    用一个已存在的对象,创建新的对象,不会调用普通构造函数, 而是调用拷贝构造函数。如果类中没有定义拷贝构造函数,编译器将提供一个默认的拷贝构造函数,它的功能是把已存在对象的成员变量,赋值给新对象的成员变量。

    用一个已存在的对象,创建新的对象语法:

    类名  新对象名(已存在的对象名);
    类名  新对象名 = 已存在的对象名;
    

    拷贝构造函数的调用场景

    \color{red}{拷贝构造函数的调用场景}

    • 用一个已存在的对象,创建新的对象
    • 以值传递的方式调用函数时, 如果实参为对象,会调用拷贝构造函数
    void fun(Person per) {
        per.show();
    }
    
    int main() {
        Person per1;
        per1.m_name="张三";
        per1.m_age=22;
        fun(per1);
        return 0;   
    }
    
    image.png
    • 函数以值的方式返回对象时,可能会调用拷贝构造函数(linux不会,编译器做了优化)

    拷贝构造函数的语法

    • 访问权限必须是public
    • 方法名必须和类名相同
    • 没有返回值,不写void
    • 如果类中定义了拷贝构造函数,编译器将不提供拷贝构造函数
    类名 (contst 类名& 对象名) {}
    
    #include <iostream>
    #include<string>
    using namespace std;
    
    class Person{
        public:
            string m_name;
            int    m_age;
            Person() {
                m_name.clear();  
                m_age = 0;
                cout <<"调用了Person()构造函数"<<endl;
            }
    
            //拷贝构造函数
            Person(const Person& refPer) {
                this->m_name = refPer.m_name;
                this->m_age = refPer.m_age;
                cout <<"调用了Person()拷贝构造函数"<<endl;
            }
    
            ~Person() {
                cout <<"调用了~Person()析构函数"<<endl;
            }
            void show() {
                cout <<" 姓名:"<<m_name<<"  年龄:"<<m_age<<endl;
            }
    };
    
    int main() {
        Person per1;
        per1.m_name="张三";
        per1.m_age=22;
        Person per2(per1);
        per2.show();
        // Person per3 = per1;
        return 0;   
    }
    
    image.png

    重载拷贝构造函数

    • 如果类中提供了重载的拷贝构造函数,没有默认的拷贝构造函数,编译器也会提供给默认的拷贝构造函数。
    #include <iostream>
    #include<string>
    using namespace std;
    
    class Person{
        public:
            string m_name;
            int    m_age;
            Person() {
                m_name.clear();  
                m_age = 0;
                cout <<"调用了Person()构造函数"<<endl;
            }
    
            //拷贝构造函数
            Person(const Person& refPer) {
                this->m_name = refPer.m_name;
                this->m_age = refPer.m_age;
                cout <<"调用了Person()拷贝构造函数"<<endl;
            }
    
            //拷贝构造函数
            Person(const Person& refPer, int it) {
                this->m_name = refPer.m_name;
                this->m_age = refPer.m_age - it;
                cout <<"调用了Person()拷贝构造函数 it = "<<it<<endl;
            }
    
    
            ~Person() {
                cout <<"调用了~Person()析构函数"<<endl;
            }
            void show() {
                cout <<" 姓名:"<<m_name<<"  年龄:"<<m_age<<endl;
            }
    };
    
    
    int main() {
        Person per;
        per.m_name="张三";
        per.m_age=22;
        Person per2(per, 2);
        per2.show();
        return 0;   
    }
    
    
    image.png

    深拷贝

    类的成员属性,如果有指向堆内存的指针,在拷贝构造函数里,需要深拷贝,即new出来同样大小的内存,然后把值复制到new出来的内存里。

    #include <iostream>
    #include<string>
    using namespace std;
    
    class Person{
        public:
            string m_name;
            int    m_age;
            int * m_ptr; // 指针成员,计划使用堆内存
            Person() {
                m_name.clear();  
                m_age = 0;
                m_ptr = nullptr;
                cout <<"调用了Person()构造函数"<<endl;
            }
    
            //拷贝构造函数
            Person(const Person& refPer) {
                this->m_name = refPer.m_name;
                this->m_age = refPer.m_age;
                this->m_ptr = new int;
                // *m_ptr = *refPer.m_ptr;  拷贝数据
                memcpy(m_ptr, refPer.m_ptr, sizeof(int)); // 拷贝数据
                cout <<"调用了Person()拷贝构造函数"<<endl;
            }
    
            ~Person() {
                delete m_ptr;
                m_ptr = nullptr;
                cout <<"调用了~Person()析构函数"<<endl;
            }
            void show() {
                cout <<" 姓名:"<<m_name<<"  年龄:"<<m_age <<"  m_ptr的值:"<<*m_ptr<<"  m_ptr的地址:"<<m_ptr  <<endl;
            }
    };
    
    
    int main() {
        Person per;
        per.m_name="张三";
        per.m_age=22;
        per.m_ptr = new int(3);
        Person per2 = per;
        per2.show();
        return 0;   
    }
    

    相关文章

      网友评论

          本文标题:c++拷贝构造函数

          本文链接:https://www.haomeiwen.com/subject/muhjtdtx.html