-
构造函数
-
构造函数长什么样子
-
函数名和类名相同
-
没有返回值
-
如果不写构造函数,任何类中都存在一个默认的构造函数
-
默认的构造函数是无参的。
-
当我们自己写了构造函数,默认的构造函数就不存在
-
-
构造函数在构造对象的时候调用
-
delete可以用来删掉默认的函数
-
指定使用默认的无参构造函数,用default说明
-
允许构造函数调用另一个构造函数,只是要用初始化参数列表的写法
-
初始化参数列表 : 只有构造函数
-
构造函数名(参数1,参数2,...):成员1(参数1),成员2(参数2),...{}
-
避免形参名和数据成员名相同的导致问题
-
-
-
构造函数干嘛的
-
构造函数用来构造对象
-
构造函数更多是用来初始化数据成员
-
-
思考题?
-
为什么不写构造函数可以构造对象? 是因为存在一个默认的无参构造函数,所以可以构造无参对象
-
构造函数重载为了什么? 为了构造不同长相的对象。
-
-
#include<iostream> #include <string> using namespace std; class Heroes { public: //如果不写构造函数,任何类中都存在一个默认的无参构造函数Heroes(){}; //Heroes() = delete; 删掉默认的构造函数 //构造函数: Heroes(string name,int level) { m_name = name; m_levels = level; cout << "调用了构造函数" << endl;//测试是否调用构造函数 } //使用初始化参数列表的方法 Heroes(string name, int level, string position) :m_name(name), m_levels(level), m_position(position) { cout << "使用初始化参数列表的方式" << endl; } //构造函数调用另一个构造函数 Heroes(string position) :Heroes("赵信",18) { m_position = position; cout << "构造函数调用构造函数" << endl; } Heroes() = default; //使用的是默认无参构造函数 void print() { cout<< m_name << " " << m_levels <<" " <<m_position<< endl; } protected: string m_name="阿索"; int m_levels=18; string m_position = "Mid"; private: }; //为了能够构造不同长相的对象,给构造函数缺省处理 class Heroines { public: Heroines(string name="", int level=0,string position="") { m_name = name; m_levels = level; m_position = position; cout << "调用缺省构造函数" << endl; } //上面函数 等效可以实现下面四个函数的功能 //Heroines() {} //Heroines(string name) { m_name = name; } //Heroines(string name, int level) { // m_name = name; // m_levels = level; //} //Heroines(string name, int level,string position) { // m_name = name; // m_levels = level; // m_position = position; //} void print() { cout << m_name << " " << m_levels << " " << m_position << endl; } protected: string m_name=""; int m_levels; string m_position=""; }; int main() { Heroes hero1; hero1.print(); Heroes hero2 = { "永恩",17 }; hero2.print(); Heroes hero3 = { "盖伦",16,"Top"}; hero3.print(); Heroes hero4 = { "Jug" }; hero4.print(); Heroines heroine1; heroine1.print(); Heroines heroine2 = {"雷欧娜"}; heroine2.print(); Heroines heroine3 = { "佐伊",18 }; heroine3.print(); Heroines heroine4 = { "辛德拉",18 ,"Mid"}; heroine4.print(); return 0; }
-
-
析构函数
-
析构函数长什么样子?
-
无返回值
-
无参数
-
函数名: ~类名
-
不写的话会存在默认的析构函数
-
析构函数不需要自己 调用,对象死亡的之前会调用析构函数
-
-
析构函数用来干嘛?(什么时候需要自己手动写析构函数)
-
当类中的数据成员是指针,并且动态申请内存就需要手写析构
-
析构函数用来释放数据成员申请动态内存
-
-
#include<iostream> #include <string> #include<cstring> using namespace std; class Heroes { public: Heroes(const char*name, int levels) { p_name = new char[strlen(name)+1]; strcpy(p_name, name); m_levels = levels; } void print() { cout << p_name << " " << m_levels << endl; } ~Heroes() { cout << "调用析构函数" << endl; delete[]p_name; p_name = nullptr; } protected: char* p_name ; int m_levels ; private: }; int main(){ { Heroes hero1("赵信", 18); hero1.print(); }//语句结束调用析构函数 cout << "测试1" << endl; //new一个对象的时候,只有delete 才会调用析构函数 { Heroes* hero2 = new Heroes("盖伦", 15); hero2->print(); cout << "测试1" << endl; delete hero2; cout << "测试2" << endl; hero2 = nullptr; } return 0; }
-
-
拷贝构造函数
-
拷贝构造函数也是构造函数,长相和构造函数一样的,只是参数是固定
-
拷贝构造函数唯一的参数是对对象引用
-
-
不写拷贝构造函数,也存在一个默认的拷贝构造函数
-
拷贝构造函数作用: 通过一个对象去初始化另一个对象
-
问题?
-
什么时候调用拷贝构造?
-
当通过一个对象去创建出来另一个新的对象时候需要调用拷贝
-
-
拷贝构造什么时候需要加const修饰参数?
-
当存在匿名对象赋值操作的时候,必须要const修饰
-
-
-
#include<iostream> #include <string> using namespace std; class Heroes { public: Heroes(string name, int level, string position) :m_name(name), m_levels(level), m_position(position) { cout << "调用构造函数" << endl; } Heroes() = default; //使用的是默认无参构造函数 //拷贝构造函数作用: 通过一个对象去初始化另一个对象 //拷贝构造:拷贝构造函数唯一的参数是对对象引用 Heroes(const Heroes& hero) { m_name = hero.m_name; m_levels = hero.m_levels; m_position = hero.m_position; cout << "拷贝构造函数" << endl; } void print() { cout << m_name << " " << m_levels << " " << m_position << endl; } protected: string m_name; int m_levels ; string m_position; private: }; int main() { Heroes hero1 = { "永恩",18,"Mid" }; hero1.print(); //通过一个对象创建另一个对象 cout << "显式调用:" << endl;//在程序中能找到相应的调用代码,或者说是手动调用的 Heroes hero2(hero1); hero2.print(); cout << "隐式调用:" << endl;//程序中找不到相应的调用代码,或者说是编译器自动调用的 Heroes hero3 = hero1; hero2.print(); //通过运算符重载的方式,没有调用拷贝构造函数 Heroes hero4; hero4 = hero1; hero4.print(); //匿名对象创建对象时候,拷贝构造一定要用const修饰 Heroes hero5 = Heroes("波比", 16,"Top");//这里调用了拷贝构造函数(隐式调用)? hero5.print(); //无名对象 匿名对象 Heroes hero6; hero6 = Heroes("嘉文", 18,"Jug"); hero6.print(); return 0; }
-
-
深浅拷贝
- 浅拷贝: 默认的拷贝构造叫做浅拷贝
- 深拷贝: 拷贝构造函数中做了new内存操作,并且做拷贝赋值的操作
-
#include<iostream> #include <string> #include<cstring> using namespace std; class Heroes { public: Heroes(const char* name, int levels) { p_name = new char[strlen(name) + 1]; strcpy(p_name, name); m_levels = levels; } void print() { cout << p_name << " " << m_levels << endl; } //浅拷贝: 默认的拷贝构造叫做浅拷贝 //深拷贝 : 拷贝构造函数中做了new内存操作,并且做拷贝赋值的操作 Heroes(const Heroes&hero):m_levels(hero.m_levels) { p_name = new char[strlen(hero.p_name)+1]; //p_name=hero.name;//这样依然是浅拷贝 strcpy(p_name, hero.p_name); } ~Heroes() { cout << "调用析构函数" << endl; delete[]p_name; p_name = nullptr; } protected: char* p_name; int m_levels; private: }; int main() { Heroes hero1("赵信", 18); Heroes hero2(hero1); Heroes hero3 = hero1; /* 浅拷贝使用hero1、hero2、hero2中的p_name指 向同一段内存,程序结束时会多次调用析构函数,多次释放同一段内存 */ hero1.print(); hero2.print(); hero3.print(); return 0; }
-
构造和析构顺序
-
普通对象,构造顺序和析构顺序是相反
-
new出来的对象,delete会直接调用析构函数
-
static对象,当程序关闭的时候,生命周期才结束,所以是最后释放
-
#include <iostream> #include <string> using namespace std; class sequence { public: sequence(string ch = "x") :m_ch(ch) { cout << ch; } ~sequence() { cout << m_ch; } protected: string m_ch; }; int main() { { sequence sign1("A"); //A static sequence sign2("B"); //AB 程序关闭时候才死亡,最后析构 sequence* psign = new sequence("C"); //ABC sequence sign4[4]; //ABCxxxx delete psign; //ABCxxxxC delete 直接调用析构 psign = nullptr; } //ABCxxxxCxxxxAB return 0; }
-
- 作业:简单写个自己的myString类
#include<iostream> #include <cstring> using namespace std; class myString { public: myString(const char*str="") { nSize = strlen(str) + 1; this->str = new char[nSize]; strcpy(this->str, str); } myString(const myString& object) { nSize = object.nSize; this->str = new char[nSize]; strcpy(this->str, object.str); } char* c_str() { return str; } char* data() { return str; } myString append(const myString&object) { myString temp; temp.nSize = this->nSize + object.nSize-1; temp.str = new char[temp.nSize]; int nCount = 0; for (int i=0;i<this->nSize-1;i++) { temp.str[nCount++] = this->str[i]; } for (int i = 0; i < object.nSize; i++) { temp.str[nCount++] =object.str[i]; } return temp; } int compare(const myString& object) { return strcmp(str, object.str); } ~myString() { delete[]str; str = nullptr; } protected: char* str; int nSize; private: }; int main() { //1.实现string中创建方式 myString str1; myString str2("ILoveyou"); myString str3(str1); myString str4 = str2; //2.通过实现data和c_str函数 打印字符串 cout << str2.c_str() << endl; //打印ILoveyou cout << str2.data() << endl; //打印ILoveyou //3.实现append 实现字符串的链接 myString strOne = "one111"; myString strTwo = "two111"; myString strThree = strOne.append(strTwo); cout << strThree.data() << endl; //onetwo //4.实现字符串比较 cout << strOne.compare(strTwo) << endl; //0 return 0; }
4.构造函数与析构函数
最新推荐文章于 2024-06-07 20:11:45 发布