1.构造函数
构造函数没有返回值
函数名和类名相同
任何类都存在默认的构造函数,默认构造函数是无参的,当我们写了任何一个构造函数时,默认 构造函数将会不存在 我们也可以通过delete 删除默认的构造函数,或者使用default说明我们使 用默认构造函数(官方的解释是我们写的无参的构造函数,没有它们提供的速度快);
构造函数允许调用另外一个构造函数,这种是委托构造,只是需要用初始化参数列表的方式去写
贴代码:
#include<iostream>
using 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.析构函数
析构函数 无返回值 无参数,所以不能重载
不写的话也存在默认的析构函数
写法: ~类名 波浪线+类名 析构函数在对象死亡前将自动调用,无需手动调用
析构函数的用法 在数据成员存在指针并且做了动态内存申请的时候,用来释放自由存储区;
#include<iostream>
using 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 拷贝函数的参数
#include<iostream>
using 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内存操作,并且做拷贝赋值的操作
因为上面我们讲过 做了动态内存申请的时候,我们要用析构函数做释放内存的操作,拷贝构造
将指针上面指向拷贝过去,但每一个对象死亡时,都会调用析构,导致同一内存段多次释放,导致程序崩溃,深拷贝就算为了预防这样的问题出现
#include<iostream>
using 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之后会立马调用析构。。。
#include<iostream>
using 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 <iostream>
#include <string>
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<iostream>
#include<cstring>
#include<string>
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] = '\0';
break;
}
else if (pstr[i+1] == '\0')
{
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'\0'12455");
Mystring str5 = "456";
cout << str5.appstr(str2) << endl;
string a123;
cout<<str4.c_str()<<endl;
while (1);
return 0;
}
附上运行截图: