本节主要讲类的类的组合的基本概念、类的封装的基本概念以及类成员作用域的问题,最后实现了一个计算器的运算类。
类的组合
有很多类还可以下分小类,一个大类的由若干个小类组成,大类产生小类称为类的继承。
类的封装
类的封装主要分为两个方面:①类的实现细节②类的使用方式
当使用类时,不需要关心类的具体实现细节,当创建一个类时,才要考虑其内部的实现细节。
基本概念
类的属性:主要通过类中的成员变量来表示的。并不是每一个类的属性都是对外公开的。然后一些类的属性却需要对外公开,这样就需要在类的表示法中定义类的属性和级别。
类的封装:C++中用于表示类的属性的变量成为成员变量,用于表示类的行为的函数称为成员函数。
访问级别:可以给类的属性和类的成员函数定义访问级别。①public:成员变量和成员函数可以在类的内部和外部访问和调用。②private:成员变量和成员函数只能在类的内部访问和调用。
基本例程如下:
#include <stdio.h>
struct Computer
{
bool Cpu;
bool Neicun;
int a();
};
struct Dell:Computer
{
public:
bool hp;
char Japan;
private:
int b()
{
printf ("Thist is Dell\n");
}
};
struct Lenovo:Computer
{
bool lenovo;
char China;
int c()
{
printf ("L\n");
return 0;
}
};
int main()
{
Dell dell;
dell.hp = 1;
dell.Japan = 'j';
//dell.b(); //无法访问,因为b()成员函数的属性是private
Lenovo lenovo;
lenovo.lenovo = 1;
lenovo.c();
return 0;
}
子类中的类成员函数可以访问父类中的类成员函数,如果子类的成员属性是public,同时定义了类的对象,同样可以通过对象来访问。
#include <stdio.h>
struct Computer
{
bool Cpu;
bool Neicun;
int a()
{
printf ("Computer\n");
return 0;
}
};
struct Dell:Computer
{
public:
bool hp;
char Japan;
int f()
{
a();
return 0;
}
private:
int b()
{
printf ("Thist is Dell\n");
}
};
struct Lenovo:Computer
{
bool lenovo;
char China;
int c()
{
printf ("L\n");
a();
return 0;
}
};
int main()
{
Dell dell;
dell.hp = 1;
dell.Japan = 'j';
//dell.b(); //无法访问,因为b()成员函数的属性是private
dell.f();
Lenovo lenovo;
lenovo.lenovo = 1;
lenovo.c();
return 0;
}
通过上面的程序可以看出,对象访问类中的成员主要由private和public属性来进行控制,同时不同的类之间的类成员的访问也是依靠这两个属性进行控制的,但是如果同一类之间的成员访问时没有限制的。
类成员的作用域
类成员的作用域都只在类的内部,外部无法直接访问,外部可以通过建立类的对象来访问类的成员(也仅仅局限于public属性的成员)。一个类中的成员函数可以直接访问成员变量并调用这个类中的其他成员函数。
类的外部可以通过类变量访问public成员,类成员的作用域与访问级别是没有关系的。
#include <stdio.h>
int i = 1;
struct A
{
private:
int i;
public:
int j;
int a()
{
i = 3;
return i;
}
};
int main()
{
int i = 2;
printf ("i = %d\n",i);
printf ("::i = %d\n",::i);
A a;
printf ("a.a() = %d\n", a.a());
//a.i = 4;
//printf ("a.i = %d\n", a.i);
return 0;
}
类成员的作用域只在类的内部,外部无法直接访问,如果外界向访问,需要通过类的对象来进行访问。这里的全局变量i被main函数中的i覆盖,::i是默认的命名空间,所以是全局的,而在类A中的函数a()属性石public,所以我们可以在main函数中进行访问,而a()使用的变量是类的内部成员变量,所以可以使用,最后的打印结果入下图所示:
struct和class
class是用于定义类的又一个关键字,它的用法和class是完全相同的。struct定义类时候类的默认属性是public,class定义类时类的默认属性石private。需要注意的是:这两个属性都是默认的属性,我们仍然可以使用public和private这两个关键字来进行约束。
#include <stdio.h>
int i = 1;
struct A
{
private:
int i;
public:
int j;
int a()
{
i = 3;
return i;
}
};
class B
{
private:
int a;
public:
int i()
{
printf ("hello world\n");
return 0;
}
};
int main()
{
A a;
//a.i;这里的i无法访问,因为属性石private
B b;
b.i(); //这里的成员函数i()可以被访问,因为它的属性是public
return 1;
}
课后练习
要求:
没有进行类封装的程序如下:
#include <stdio.h>
struct Operator
{
private:
double ob;
double oc;
char oa;
public:
bool setOperator(char a)
{
bool ret = false;
if ((a == '+') || (a == '-') || (a == '*') || (a == '/'))
{
oa = a;
ret = true;
return ret;
}
else
{
ret = false;
return ret;
}
}
void setPatameter(double b, double c)
{
ob = b;
oc = c;
}
bool result(double& d)
{
bool ret = true;
switch (oa)
{
case '/':
{
if ((oc > -0.000001) && (oc < 0.0000001))
{
ret = false;
}
else
{
d = ob / oc;
}
break;
}
case '+':
{
d = ob + oc;
break;
}
case '*':
{
d = ob * oc;
break;
}
case '-':
{
d = ob - oc;
break;
}
default:
ret = false;
break;
}
return ret;
}
};
int main()
{
double aa = 0;
Operator o;
o.setOperator('/');
o.setPatameter(2,0);
o.result(aa);
printf ("%f\n",aa);
return 1;
}
进行类封装之后的程序:
main.cpp
#include <stdio.h>
#include "o.h"
int main()
{
double aa = 0;
Operator o;
o.setOperator('/');
o.setPatameter(2,0);
o.result(aa);
printf ("%f\n",aa);
return 1;
}
o.cpp
#include "o.h"
bool Operator::setOperator(char a) //这里需要指明setOperator是哪个类的函数,要不然setOperator将会成为全局函数
//这里的表示方法是使用::
{
bool ret = false;
if ((a == '+') || (a == '-') || (a == '*') || (a == '/'))
{
oa = a;
ret = true;
return ret;
}
else
{
ret = false;
return ret;
}
}
void Operator::setPatameter(double b, double c)
{
ob = b;
oc = c;
}
bool Operator::result(double& d)
{
bool ret = true;
switch (oa)
{
case '/':
{
if ((oc > -0.000001) && (oc < 0.0000001))
{
ret = false;
}
else
{
d = ob / oc;
}
break;
}
case '+':
{
d = ob + oc;
break;
}
case '*':
{
d = ob * oc;
break;
}
case '-':
{
d = ob - oc;
break;
}
default:
ret = false;
break;
}
return ret;
}
o.h
#ifndef _O_H
#define _O_H
struct Operator
{
private:
double ob;
double oc;
char oa;
public:
bool setOperator(char a);
void setPatameter(double b, double c);
bool result(double& d);
};
#endif