C++核心编程 面向对象 类和对象-对象的初始化和清理
#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; }
#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; }
#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; }
#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; }
解决办法:浅拷贝的问题利用深拷贝来解决--自己实现拷贝函数,不使用系统默认给的拷贝函数
Person(const Person &p) { cout << "Person 拷贝构造函数调用" << endl; m_Age = p.m_Age; //m_height = p.m_Age;// 编译器默认使用这一行 //深拷贝// m_height = new int(*p.m_height); }
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 }
#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; }
#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; }