C++ 面向对象  类和对象-对象的初始化和清理_拷贝构造函数

 

C++ 面向对象  类和对象-对象的初始化和清理_#include_02

 

 

#include <iostream>
using namespace std;
#include <string>

//对象的初始化和清理
//1、构造函数 进行初始化操作
class Person {
public:
    //1.1 构造函数
    //没有返回值  不同写void
    //函数名 与类名相同
    //构造函数可以有参数  可以发生重载
    //创建对象的时候  构造函数会自动调用  而且只调用一次

    Person() {
        cout << "Person 构造函数的调用" << endl;
    }


    //2 析构函数  进行清理的操作
    //没有返回值  不写void 
    // 函数名和类名相同 在名称前加~
    //析构函数不可以有参数的,不可以发生重载
    //    对象在销毁前 会自动调用析构函数  而且只会调用一次

    ~Person() {
        cout << "析构函数的调用" << endl;
    
    }
};

void test01() {

    Person  p;//在栈上的数据  test01 执行完毕之后  释放这个对象
}

int  main() {
    test01();
    
    system("pause");
    return 0;

}

C++ 面向对象  类和对象-对象的初始化和清理_#include_03

 

 

#include <iostream>
using namespace std;
#include <string>

//构造函数的分类以及调用
//分类
//按照参数分类 无参数构造(默认构造) 和有参数构造
//按照类型分类  普通构造 和 拷贝构造函数
class Person {
public:
    //1.1 构造函数


    Person() {
        cout << "Person 构造函数的调用" << endl;
    }

    Person( int a)
    {
        age = a;
        cout << "Person 有参数 构造函数的调用" << endl;
    }

    //拷贝构造函数
    Person(const Person  &p) {
        //将传入的人身上的所有属性,拷贝到我身上
        age = p.age;
        cout << "Person 拷贝函数的调用" << endl;
    
    }
    int age;
    //2 析构函数  进行清理的操作


    ~Person() {
        cout << "Person 析构函数的调用" << endl;

    }
};

//调用
void test01() {

    //Person  p;//在栈上的数据  test01 执行完毕之后  释放这个对象

    //1 括号法
    //默认构造函数调用
    //Person p1;
    //有参函数调用
    //Person p2(10);

    /*拷贝构造函数*/
    //Person p3(p2);
    //注意事项  调用构造默认函数的时候,不要加小括号;
    //因为下面这行代码,编译器会认为是一个函数的声明,不会认为在创建对象
    //Person p1();
    //void func();


    //显示法
    Person p1;
    Person p2 = Person (10);//有参构造调用
    Person p2 = Person(p2); //拷贝构造

    //Person(10);//Person(10);相当于匿名对象 特点:当前执行结束后,系统会立即回收掉匿名对象

    //注意事项2 
    //不要利用拷贝构造函数  初始化匿名对象 编译器会认为 Person (p3) == Person p3  对象声明
    //Person(p3);

    //3、隐式转换法
    Person  p4 = 10;//相当于 写了  Person p4 = Person(10);  有参构造
    Person p5 = p4; //拷贝构造
}

int  main() {
    test01();

    system("pause");
    return 0;

}

C++ 面向对象  类和对象-对象的初始化和清理_#include_04

 

 

#include <iostream>
using namespace std;
#include <string>

//拷贝构造函数的调用时机


class Person {
public:
    Person() {
        cout << "Person 默认构造函数的调用" << endl;
    }
    Person(int age) {
        m_Age = age;
        cout << "Person 有参构造函数的调用" << endl;
    }
    Person(const Person &p) {
        m_Age = p.m_Age;
        cout << "Person拷贝构造函数的调用" << endl;
    }

    ~Person() {
        cout << "Person 析构函数的调用" << endl;
    }

    int m_Age;

};
//1 使用一个已经创建完毕的对象来初始化一个新对象

void test01() {
    Person p1(20);
    Person p2(p1);
     
    cout << "p2的年龄" << p2.m_Age << endl;

}
//2 值传递的方式给函数参数传值
void dowork(Person p) {
    

}

void test02() {

    Person p;
    dowork(p);
}

//3 值方式返回局部对象
Person dowork2() {
    Person p1;
    return p1;

}

void test03() {

    Person p = dowork2();

}


int  main() {
    //test01();
    //test02();
    test03();
    system("pause");
    return 0;

}

C++ 面向对象  类和对象-对象的初始化和清理_#include_05

 

 C++ 面向对象  类和对象-对象的初始化和清理_析构函数_06

 

#include <iostream>
using namespace std;
#include <string>

//深拷贝与浅拷贝


class Person {
public:
    Person() {
        cout << "Person 默认构造函数的调用" << endl;
    }
    Person(int age, int height) {

        m_Age = age;
        m_height = new int(height);
        cout << "Person 有参构造函数的调用" << endl;
    }


    ~Person() {
        //将我们堆区开辟的数据做释放操作
        if (m_height != NULL) {
            delete m_height;
            m_height = NULL;
        }
        cout << "Person 析构函数的调用" << endl;
    }

    int m_Age;
    int *m_height;

};
//1 使用一个已经创建完毕的对象来初始化一个新对象

void test01() {
    Person p1(18,160);
    //Person p2(p1);
    //cout << "p1的升高" << p1.m_Age << endl;
    cout << "p1的年龄" << p1.m_Age << "p1的升高"<<*p1.m_height<< endl;

    Person p2(p1);//p2 用括号法创建出对象  p2调用拷贝构造函数
    cout << "p2的年龄" << p2.m_Age << "p1的升高"<<*p2.m_height<< endl;
}


int  main() {
    test01();
    
    
    system("pause");
    return 0;

}

 

 C++ 面向对象  类和对象-对象的初始化和清理_构造函数_07

 

 C++ 面向对象  类和对象-对象的初始化和清理_析构函数_08

 

解决办法:浅拷贝的问题利用深拷贝来解决--自己实现拷贝函数,不使用系统默认给的拷贝函数

 

Person(const Person &p) {
        
        cout << "Person 拷贝构造函数调用" << endl;
        m_Age = p.m_Age;
        //m_height = p.m_Age;// 编译器默认使用这一行
        //深拷贝//
        m_height = new int(*p.m_height);
    
    }

C++ 面向对象  类和对象-对象的初始化和清理_析构函数_09

 

 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 //传统意义的函数变量赋初值
 6 class Person {
 7 
 8 public:    
 9     //有参构造函数
10     //Person(int a,int b,int c) {
11     //    m_a = a;
12     //    m_b = b;
13     //    m_c = c;    
14     //
15     //}
16 
17     //初始化列表初始化属性
18     /*Person() :m_a(10), m_b(20), m_c(30) {
19     
20     }*/
21     Person(int a,int b,int c) :m_a(a), m_b(b), m_c(c) {
22 
23     }
24     int m_a;
25     int m_b;
26     int m_c;
27 };
28 
29 
30 void test01() {
31     //Person p(10, 20, 30);
32     Person p(1,2,3);
33     cout << "m_a的值" << p.m_a << endl;
34     cout << "m_b的值" << p.m_b << endl;
35     cout << "m_c的值" << p.m_c << endl;
36 
37 
38 }
39 
40 int main() {
41     test01();
42 
43     system("pause");
44     return 0;
49 }

C++ 面向对象  类和对象-对象的初始化和清理_构造函数_10

 

 

#include <iostream>
using namespace std;
#include<string>
//类对象做类成员
//手机类
class Phone {

public:
    Phone(string pname) {
    
        m_PName = pname;
    }


    //手机品牌的名称
    string m_PName;


};




//人类
class Person {

public:
    //Phone m_Phone = pName  创建对象的时候的隐式转换法
    Person(string name,string pName):m_Name(name),m_phone(pName) {
    
    }

    //姓名
    string m_Name;
    //手机
    Phone m_phone;



};


//当其他类的对象作为本类成员,构造时候先构造对象,再构造自身;析构的顺序:析构的顺序与构造相反
void test01() {
    Person p("张三","苹果Max");
    cout << p.m_Name << "拿着" << p.m_phone.m_PName << endl;

}

int main() {
    
    test01();
    system("pause");
    return 0;




}

C++ 面向对象  类和对象-对象的初始化和清理_#include_11

 

 

#include <iostream>
using namespace std;
#include <string>

//静态成员函数  所有对象共享同一个函数  静态成员函数智能访问静态成员变量


class Person {
public:
    //静态成员函数

    static void func() {
        m_A = 100;//静态成员函数 可以访问静态成员变量
        //
        //m_B = 200;//静态成员函数 不可以访问  非静态成员变量 ,无法区分到底是哪个对象的m_B
        cout << "static func函数的调用" << endl;    
    }
    //静态成员变量的特点   类内进行声明  类外进行初始化
    static int m_A;//静态成员 变量
    int m_B;//非静态成员变量
    //静态成员函数  也是有访问权限的 

};
//静态成员变量的特点   类内进行声明  类外进行初始化
int Person::m_A = 0;

//有两中访问方式
void test01() {
    //1、通过对象访问
    Person p;
    p.func();

    //2、通过类名访问
    Person::func();
    
}


int  main() {
    test01();


    system("pause");
    return 0;

}