类的结构
class text{
public:
//公有数据成员
//公有成员函数
protected:
//保护数据成员
//保护成员函数
private:
//私有数据成员
//私有成员函数
};
普通成员函数
#include <iostream>
using namespace std;
class text{
public:
void fun(int a,int b);
void prit();
private:
int num1;
int num2;
};
void text::fun(int a,int b)
{
num1=a;
num2=b;
}
void text::prit(void)
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
text op1;
op1.fun(1,2);
op1.prit();
return 0;
}
运行结果
num1=1 num2=2
注意
1、不能在类里面直接给成员函数赋值
2、类是是一种类型,只有定义了对象后系统才会为对象分配存储空间,以存放对象中的成员。并不是说类不占据内存空间的,要注意一个空类的字节大小为1.
3、在类的内部所有成员之间都可以通过成员函数直接访问,但是类的外部不能访问对象的私有成员。
内联成员函数
内联函数要注意
.
内联函数里面不能含有for、switch、while等,尽可能的简单防止出现错误或者数据沉凹。
隐式声明:
#include <iostream>
using namespace std;
class text{
public:
void fun(int a,int b)
{
num1=a;
num2=b;
}
void prit()
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
private:
int num1;
int num2;
};
int main()
{
text op1;
op1.fun(1,2);
op1.prit();
return 0;
}
显示声明
#include <iostream>
using namespace std;
class text{
public:
inline void fun(int a,int b);// inline可以省略不写
inline void prit();
private:
int num1;
int num2;
};
inline void text::fun(int a,int b)
{
num1=a;
num2=b;
}
inline void text::prit()
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
text op1;
op1.fun(1,2);
op1.prit();
return 0;
}
对象可以访问公有成员变量,私有不行。
构造和析构函数
构造函数
构造函数有什么用?
简单点来说就是初始化类里面的成员变量
1、构造函数名称必须和类重名
2、构造函数可带参也可不带参
3、构造函数函数体写在类内部或者外部都可以
4、构造函数不可以有返回值,不可用void
#include <iostream>
using namespace std;
class text{
public:
text(int a);
void prit();
private:
int num1;
int num2;
};
text::text(int a)
{
num1=a;
num2=3;
}
void text::prit()
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
text op1(0);//声明对象的时候,自动调用构造函数
op1.prit();
return 0;
}
构造函数还可以这样调用
int main()
{
text * op1=new text(0);
op1->prit();
return 0;
}
构造函数定义时候还可以默认带参
text(int a=0);
析构函数
析构函数主要作用时间是类结束时候使用的,自动调用。主要是做一些清理工作
1、析构函数必须和构造函数同名,前面加一个~
2、析构函数不能有返回值(void也不行),不能有参数,而且不能重载,一个类中只能有一个析构函数
3、当撤销对象时,编译系统会自动调用析构函数
4、每个类都必须有一个析构函数,如果没有写,系统会自动生成一个析构函数:
类名::类名()
{ }
#include <iostream>
using namespace std;
class text{
public:
text(int a);
~text();
void prit();
private:
int num1;
int num2;
};
text::text(int a)
{
cout<<"构造函数使用中"<<endl;
num1=a;
num2=3;
}
text::~text()
{
cout<<"析构函数使用中"<<endl;
}
void text::prit()
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
text op1(0);
op1.prit();
return 0;
}
运行结果
构造函数使用中
num1=0 num2=3
析构函数使用中
我们改一下main函数
int main()
{
text *op1=new text(0);
op1->prit();
return 0;
}
运行结果
构造函数使用中
num1=0 num2=3
为什么这样的构造函数调用析构没有运行呢?
因为new后没有delete。也就是对象没有结束。所以类没有销毁
改正
int main()
{
text *op1=new text(0);
op1->prit();
delete op1;
return 0;
}
运行结果
构造函数使用中
num1=0 num2=3
析构函数使用中
拷贝构造函数
自定义拷贝构造函数
#include <iostream>
using namespace std;
class text{
public:
text(int a);//构造函数
text(const text &p);//自定义构造函数
~text();//析构函数
void prit();
private:
int num1;
int num2;
};
text::text(int a)
{
cout<<"构造函数使用中"<<endl;
num1=a;
num2=3;
}
text::text(const text &p)
{
num1=p.num1;
num2=p.num2;
}
text::~text()
{
cout<<"析构函数使用中"<<endl;
}
void text::prit()
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
text op1(0);
op1.prit();
text op2(op1);
op1.prit();
return 0;
}
这种调用写法也没有问题
int main()
{
text op1(0);
op1.prit();
text op2=op1;
op1.prit();
return 0;
}
结果:
构造函数使用中
num1=0 num2=3
num1=0 num2=3
析构函数使用中
析构函数使用中
分析
为什么在最后析构?因为return 0时候才资源回收,内存释放.
默认拷贝构造函数
#include <iostream>
using namespace std;
class text{
public:
text(int a);//构造函数
~text();//析构函数
void prit();
private:
int num1;
int num2;
};
text::text(int a)
{
cout<<"构造函数使用中"<<endl;
num1=a;
num2=3;
}
text::~text()
{
cout<<"析构函数使用中"<<endl;
}
void text::prit()
{
cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
text op1(0);
op1.prit();
text op2=op1;
op1.prit();
return 0;
}
运行结果
构造函数使用中
num1=0 num2=3
num1=0 num2=3
析构函数使用中
析构函数使用中
深拷贝与浅拷贝
我们写这样一个程序
#include <iostream>
#include <cstring>
using namespace std;
class text{
public:
text(char * str,int num);//构造函数
~text();//析构函数
void prit();
private:
char * name;
int old;
};
text::text(char * str,int num)
{
cout<<"构造函数使用中"<<endl;
name= new char[strlen(str)+1];
strcpy(name,str);
old=num;
}
text::~text()
{
cout<<"析构函数使用中"<< name<<endl;
delete []name;
}
void text::prit()
{
cout<<"name="<<name<<" old="<<old<<endl;
}
int main()
{
text op1("哈哈",99);
op1.prit();
text op2=op1;
op2.prit();
return 0;
}
我在Windows下的codeblocks运行没有问题
实际上是不能运行的,创建对象op1时候调用了构造函数,创建对象op2的时候:text op2=op1;使用默认的拷贝构造函数,op2并没有调用text::text(char * str,int num)函数。op2使用的内存其实还是op1的。但是析构运行了两次,就是释放了两次,所以说肯定是报错的。我在Linux运行同样的代码
结果就报错了。
解决方法:
#include <iostream>
#include <cstring>
using namespace std;
class text{
public:
text(char * str,int num);//构造函数
text(const text &p);
~text();//析构函数
void prit();
private:
char * name;
int old;
};
text::text(char * str,int num)
{
cout<<"构造函数使用中"<<endl;
name= new char[strlen(str)+1];
strcpy(name,str);
old=num;
}
text::text(const text &p)
{
cout<<"深拷贝构造"<<endl;
name=new char[strlen(p.name)];
old=p.old;
}
text::~text()
{
cout<<"析构函数使用中"<< name<<endl;
delete []name;
}
void text::prit()
{
cout<<"name="<<name<<" old="<<old<<endl;
}
int main()
{
text op1("哈哈",99);
op1.prit();
text op2=op1;
op2.prit();
return 0;
}