1.构造函数
构造函数没有返回值
函数名和类名相同
任何类都存在默认的构造函数,默认构造函数是无参的,当我们写了任何一个构造函数时,默认 构造函数将会不存在 我们也可以通过delete 删除默认的构造函数,或者使用default说明我们使 用默认构造函数(官方的解释是我们写的无参的构造函数,没有它们提供的速度快);
构造函数允许调用另外一个构造函数,这种是委托构造,只是需要用初始化参数列表的方式去写
贴代码:
#includeusing namespace std; class Fox {//Fox() = delete; //删除默认的构造函数 Fox(int data,int num):data(data),num(num) { } ;括号里面的形参用于初始化属性成员,可以避免数据成员和形参名相同导致问题 Fox(int mdata) { data=mdata; }//带参数手写的构造函数,写了任意一个构造函数之后,默认构造函数将被删除 Fox()=default;//说明我们将使用默认的无参构造函数 public: protected: int data; int num; }; int main() { Fox yue;//这里使用的就算默认的构造函数 fox yue1(18);//带参构造函数 fox yue2(19,15);//调用的初始化列表的构造函数 while(1); return 0; }
2.析构函数
析构函数 无返回值 无参数,所以不能重载
不写的话也存在默认的析构函数
写法: ~类名 波浪线+类名 析构函数在对象死亡前将自动调用,无需手动调用
析构函数的用法 在数据成员存在指针并且做了动态内存申请的时候,用来释放自由存储区;
#includeusing namespace std; class Fox { public: Fox(char *name) { str=new char[strlen(name)+1];//做了动态内存申请 strcpy(str,name); } ~Fox() //手写析构函数 { delete [] str; } protected: int data; char *str; }; int main() { { Fox yue("123"); }//离开这里 对象死亡前 自动调用析构 while(1); return 0; }
3.拷贝构造函数
拷贝构造函数也是构造函数的一种
不写拷贝构造函数,也存在一个默认的拷贝构造函数
拷贝构造函数唯一的参数是对对象引用 ,可以通过一个对象去初始化另外一个对象
存在匿名对象时,必须const 拷贝函数的参数
#includeusing namespace std; class Fox { public: Fox(const char* name) { str = new char[strlen(name) + 1];//做了动态内存申请 strcpy(str, name); } Fox(Fox& temp) { data = temp.data; str = temp.str; }//拷贝构造函数 ~Fox() //手写析构函数 { delete[] str; } protected: int data; char* str; }; int main() { Fox yueyue("yueyue"); Fox yueyue2(yueyue);//通过一个对象创建另外一个对象 ,调用拷贝构造 Fox yueyue3=yueyue2;//隐式调用 ,调用拷贝构造 }
4.深浅拷贝问题
浅拷贝: 默认的拷贝构造叫做浅拷贝
深拷贝: 拷贝构造函数中做了new内存操作,并且做拷贝赋值的操作
因为上面我们讲过 做了动态内存申请的时候,我们要用析构函数做释放内存的操作,拷贝构造
将指针上面指向拷贝过去,但每一个对象死亡时,都会调用析构,导致同一内存段多次释放,导致程序崩溃,深拷贝就算为了预防这样的问题出现
#includeusing namespace std; class Fox { public: Fox(const char* name) { str = new char[strlen(name) + 1];//做了动态内存申请 strcpy(str, name); } Fox(Fox& temp) { data = temp.data; //str = temp.str; str = new char[strlen(name) + 1];//做了动态内存申请 strcpy(str, temp.str ); //这样就是深拷贝了 }//拷贝构造函数 ~Fox() //手写析构函数 { delete[] str; } protected: int data; char* str; }; int main() { Fox yueyue("yueyue"); Fox yueyue2(yueyue);//通过一个对象创建另外一个对象 ,调用拷贝构造 Fox yueyue3
5.构造和析构顺序问题
注意点:new 出来的构造函数,
在delete之后会立马调用析构。。。
#includeusing namespace std; class yueyue { public: yueyue(int data) :data(data) {} yueyue() = default; ~yueyue() { cout << data <<"t"<< endl; } private: int data=3; }; int main() { yueyue* p = new yueyue[4]; yueyue(18); yueyue(3); yueyue(5); yueyue(9); delete[]p; yueyue(11); //18 . 3 .5 .9 . 3 3 3 3 11 return 0; }
6.C++结构体
C++结构没写构造函数之前 按照C的方法去用,写了构造函数之后要按照构造函数的标准去用
查看是否有合适参数的构造函数
#include#include using namespace std; struct Fox { //默认为公有属性 //类中默认属性是私有属性 //protected: string name; int age; public: Fox(string name) :name(name) { cout << "构造函数" << endl; } ~MM() { } }; int main() { //Fox yueyue = { "狐狸",19 }; 错误,因为没有两个参数的构造函数 Fox yueyue= { "狐狸" }; cout << yueyue.name << "t" << yueyue.age << endl; return 0;
string 作业
#include#include #include using namespace std; class Mystring { public: char *c_str() //C语言字符串 { if (pstr == nullptr) { pstr = new char[mystringlen]; } char *temp = new char[mystringlen]; memset(temp, 0, mystringlen); for (int i = 0; i <= mystringlen; i++) { if (i == mystringlen-1) { temp[i+1] = ' '; break; } else if (pstr[i+1] == ' ') { break; } else { temp[i] = pstr[i]; } } return temp; } char *cpulspuls_data() { } char *appstr(Mystring &str) //字符链接 { int count = 0; char *tempstr = new char[mystringlen + str.mystringlen] + 1; for (int i = 0; i < mystringlen-1; i++) { tempstr[i] = pstr[i]; count++; } for (int j = count; j< str.mystringlen + count; j++) { tempstr[j] = str.pstr[j - count]; } return tempstr; } Mystring() { pstr = nullptr; }//构造函数 Mystring(Mystring&str) //通过一个对象去创建另外一个对象 { pstr = new char[strlen(str.pstr) + 1]; mystringlen = strlen(str.pstr) + 1; strcpy_s(pstr, mystringlen, str.pstr); cout << "我是拷贝构造1" << endl; } Mystring(char * str) //赋值的方式 { pstr = new char[strlen(str) + 1]; mystringlen = strlen(str) + 1; strcpy_s(pstr, mystringlen, str); cout << "我是拷贝构造2" << endl; } ~Mystring() //析构函数 { cout << "析构函数" << endl; delete[]pstr; } protected: char *pstr; int mystringlen=1; }; int main() { Mystring str; Mystring str2 = "我是狐狸"; Mystring str3 = str2; Mystring str4 = Mystring("0' '12455"); Mystring str5 = "456"; cout << str5.appstr(str2) << endl; string a123; cout< 附上运行截图:



