0%

C++的类

什么是类以及类的定义

类是属于用户自定义的数据类型, 并且该类型的数据具有一定的行为能力, 也就是类中说描述的方法。通常来说, 一个类的定义包含两部分的内容, 一是该类的属性, 另一部分是它所拥有的方法

类的实质

类是一种用户自定义的引用数据类型,它的本质是数据类型,并不是数据,所以不存在于内存中,不能被直接操作,只有被实例化为对象时,才会变得可操作

类的特性

1
2
3
4
5
1、抽象;
2、封装和数据隐藏;
3、继承;
4、多态;
5、代码可重用性

类的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;
class 类名
{
public:
//公共的行为或者属性
private:
//私有的行为或属性
protected:
//
};
int main()
{

return 0;
}

成员访问类型的选择

类使用private、protected和public关键字控制成员的访问权限,类成员的默认访问权限为private
1)、private成员:能被本类的成员函数(不管是哪一种控制符声明的成员函数,都可以)、友元函数
2)、protected成员:可通过本类的成员函数(不管是哪一种控制符声明的成员函数,都可以)、友元函数、其派生类的成员函数(不管是哪一种控制符声明的成员函数,都可以)
3)、public成员:能被本类的成员函数(不管是哪一种控制符声明的成员函数,都可以)、友元函数、本类的对象、其派生类的成员函数(不管是哪一种控制符声明的成员函数,都可以);

1)、数据成员通常声明为private属性,这样可以实现数据隐藏;
2)、成员函数通常声明为public属性,这样在外部可以访问;
3)、对于类成员,若想让派生类能够访问访问而不想让外部访问,则声明为protected属性

说明:

  1. 类名需要遵循一般的命名规则
  2. publicprivate为属性/方法限制的关键字,private表示该部分内容是私密的,不能被外部所访问或者调用,只能被本类内容访问;而 public 表示公开的属性和方法, 外界可以直接访问或者调用。一般来说类的属性成员都应设置为private, public只留给那些被外界用来调用的函数接口, 但这并非是强制规定, 可以根据需要进行调整;
  3. 结束部分的分号不能忽略
  4. 定义类后,类名就是新的数据类型,即类名就像int一样可以定义变量

类的实现

在上面的定义示例中我们只是定义了这个类的一些属性和方法声明, 并没有去实现它, 类的实现就是完成其方法的过程。类的实现有两种方式, 一种是在类定义时完成对成员函数的定义, 另一种是在类定义的外部进行完成。

在类定义时定义成员函数

成员函数的实现可以在类定义时同时完成,如代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<iostream>
using namespace std;
class caculate
{
public://公共的行为或者属性
int jia(int a,int b)//实现jia函数
{
int c;
c=a+b;
return c;
}
int jian(int a,int b)//实现jian函数
{
int c;
c=a-b;
return c;
}
private://私有的行为或属性
double cheng(double a,double b)//实现cheng函数
{
double c;
c=a*b;
return c;
}
};
int main()
{
caculate M; //用定义好的类创建一个对象 M
int c=M.jia(10,20);//利用caculate类中的jia函数进行运算
cout<<c<<endl;
cout<<M.jian(10,20);//利用caculate类中的jian函数进行运算
cout<<M.cheng(20,10); //这里不能调用,会报错,因为cheng的属性时private
return 0;
}

与类的定义相比, 在类内实现成员函数不再是在类内进行声明, 而是直接将函数进行定义, 在类中定义成员函数时, 编译器默认会争取将其定义为 inline 型函数

在类外定义成员函数

在类外定义成员函数通过在类内进行声明, 然后在类外通过作用域操作符 :: 进行实现, 形式如下:

1
2
3
4
返回类型 类名::成员函数名(参数列表)
{
//函数体
}

具体用法代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<iostream>
using namespace std;
class caculate
{
public://公共的行为或者属性
int jia(int a,int b);//在类中对jia函数进行声明 ,此处别忘记分号;
int jian(int a,int b);//在类中对jian函数进行声明
private://私有的行为或属性
double cheng(double a,double b);//在类中对cheng函数进行声明
};

int caculate::jia(int a,int b)//通过作用域操作符"::"实现jia函数
{
int c;
c=a+b;
return c;
}

int caculate::jian(int a,int b)//通过作用域操作符"::"实现jian函数
{
int c;
c=a-b;
return c;
}

double cheng(double a,double b)//过作用域操作符"::"实现cheng函数
{
double c;
c=a*b;
return c;
}
int main()
{
caculate M; //用定义好的类创建一个对象 M
int c=M.jia(10,20);//利用caculate类中的jia函数进行运算
cout<<c<<endl;
cout<<M.jian(10,20);//利用caculate类中的jian函数进行运算
cout<<M.cheng(20,10); //这里不能调用,会报错,因为cheng的属性时private
return 0;
}

依 jia 成员函数来说, 在类内声明的形式为 int jia(int a,int b); 那么在类外对其定义时函数头就应该是 caculate::int jia(int a,int b) 这种形式, 其返回类型、成员函数名、参数列表都要与类内声明的形式一致

访问类成员

通过对象访问类成员

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
using namespace std;
class test
{
public:
int a=20;
double b=1.23;//数据成员
public:
void function();//成员函数
};
int main()
{
test put;//在栈上创建对象
put.a=30;//调用类中的数据 ,并修改
cout<<put.a;
return 0;
}

通过指向类的指针访问类成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
using namespace std;
class test
{
public:
int a=20;
double b=1.23;//数据成员
public:
void function();//成员函数
};
int main()
{
test *put=new test;//创建指向类的指针,在堆上创建对象
put->a=30;//通过指针访问成员数据
cout<<put->a;
return 0;
}

补充:对和栈的区别

栈(stack)是由系统自动分配和释放,例如int b;

堆(heap)是由程序员分配和释放,例如p2=new char[10]; 但注意,p2本身是在栈中的。

对象的作用域、可见域、生存周期

类对象的作用域、可见域以及生存周期与普通变量的保持相同, 当对象生存周期结束时对象被自动撤销, 所占用的内存被回收, 需要注意的是, 如果对象的成员函数中有使用 new 或者 malloc 申请的动态内存程序不会对其进行释放, 需要我们手动进行清理, 否则会造成内存泄露。