类是 C++ 的核心特性,通常被称为用户定义的类型。
类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。
定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
class Box { public: double length; // 盒子的长度 double breadth; // 盒子的宽度 double height; // 盒子的高度 };
Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box
类的对象的公共数据成员可以使用直接成员访问运算符 (.) 来访问。
#include<iostream> using namespace std; class man{ public: char name[12]; int age; #include<iostream> #include<cstring> using namespace std; class man{ public: char name[12]; int age; }; int main(){ man m1; strcpy(m1.name,"webcyh"); m1.age=12; cout<<m1.name; return 0; }
~ "19.cpp" 18L, 191C written [root@VM_0_11_centos gcc]# g++ 19.cpp -o 19.c [root@VM_0_11_centos gcc]# ./19.c webcyh[root@VM_0_11_centos gcc]#
需要注意的是,私有的成员和受保护的成员不能使用直接成员访问运算符 (.) 来直接访问。我们将在后续的教程中学习如何访问私有成员和受保护的成员。
类中的函数成员定义以及使用
#include<iostream> #include<cstring> using namespace std; class man{ public: char name[12]; int age; };
class animal{
public:
int age;
int getage();
};
int animal::getage(){
return age;
};
/*
或者
class animal{ public: int age; int getage(){
return age;
}
};
*/ int main(){ man m1;//声明一个人类 animal a1;//声明一个动物类 strcpy(m1.name,"webcyh"); m1.age=12; cout<<m1.name; a1.age=12; cout<<a1.getage(); return 0; }
[root@VM_0_11_centos gcc]# ./19.c webcyh12[root@VM_0_11_centos gcc]#
成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义
类修饰符
每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。成员和类的默认访问修饰符是 private。
class Base { public: // 公有成员 protected: // 受保护成员 private: // 私有成员 };
私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。
class Box { public: double length; void setWidth( double wid ); double getWidth( void ); private: double width; };
box.setWidth(10.0); // 使用成员函数设置宽度
// box.width = 10.0; // Error: 因为 width 是私有的
保护成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的。继承的子类也可以访问
#include<iostream> using namespace std; //Box派生出SmallBox protect修饰符的成员变量只能被派生类或者基类使用不得在外边调用 class Box{ protected: int width; }; class SmallBox:Box{ public: void setWidth(int a){ width=a; }; int getWidth(); }; int SmallBox::getWidth(){ return width; } int main(){ SmallBox b1; b1.setWidth(21); cout<<b1.getWidth(); }
[root@VM_0_11_centos gcc]# ./20.c 21[root@VM_0_11_centos gcc]#
访问权限:这里以一个protected继承为例子:
#include<iostream> using namespace std; class A{ public://公有a int a=12; A(){//构造函数 a1=12; a2=2; a3=3; }; void getAll(){ cout<<a<<endl; cout<<a2<<endl; cout<<a3<<endl; cout<<a1<<endl; };//注意这里成员变量定义与使用顺序关系不大可以随便放 public: int a1; private: int a2; protected: int a3; };//类也是一种数据结构属于自定义结构体:需要加分号 class B :protected A{//在类里面不写是什么类型,默认是 private 的。 public: int a; B(int i){ a=i; }; void getAll(){ cout<<a<<endl; cout<<a2<<endl; cout<<a3<<endl; cout<<a1<<endl; }; }; int main(){ B b(12);//声明对象类实例同时初始化 cout<<b.a1;//正常显示 基类中的public 变为protected 可以访问 cout<<b.a2;//无法正常显示 基类中的private 派生类中不可访问 cout<<b.a3;//正常显示 几类中的protected 变为派生类中的protected可以访问 cout<<b.a;//正常显示基类中为public 派生中还是public(注意这里的a是不同的一个是基类中的一个是派生类中的 首先是到派生类中寻找,再到基类中寻找) return 0; }
结果如下会出现错误
修改后:
#include<iostream> using namespace std; class A{ public://公有a int a=12; #include<iostream> using namespace std; class A{ public://公有a int a; A(){//构造函数 a1=12; a2=2; a3=3; }; void getAll(){ cout<<a<<endl; cout<<a2<<endl; cout<<a3<<endl; cout<<a1<<endl; };//注意这里成员变量定义与使用顺序关系不大可以随便放 public: int a1; private: int a2; protected: int a3; };//类也是一种数据结构属于自定义结构体:需要加分号 class B :protected A{ public: int a; B(int i){ a=i; }; void getAll(){ cout<<a<<endl; // cout<<a2<<endl; cout<<a3<<endl; cout<<a1<<endl; }; }; int main(){ B b(12);//声明对象类实例同时初始化 //cout<<b.a1;//不正常显示 基类中的public 变为protected 外部无法访问 //cout<<b.a2;//无法正常显示 基类中的private 派生类中不可访问 外部也无法访问 //cout<<b.a3;//无法正常显示 几类中的protected 变为派生类中的protected可以访问 外部无法访问 cout<<b.a;//正常显示基类中为public 派生中还是public(注意这里的a是不同的一个是基类中的一个是派生类中的 首先是到派生类中寻找,再到基类中寻找) return 0; }
总结一下三种继承方式:
继承方式 | 基类的public成员 | 基类的protected成员 | 基类的private成员 | 继承引起的访问控制关系变化概括 |
---|---|---|---|---|
public继承 | 仍为public成员 | 仍为protected成员 | 不可见 | 基类的非私有成员在子类的访问属性不变 |
protected继承 | 变为protected成员 | 变为protected成员 | 不可见 | 基类的非私有成员都为子类的保护成员 |
private继承 | 变为private成员 | 变为private成员 | 不可见 | 基类中的非私有成员都称为子类的私有成员 |
有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。
-
1.public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private
-
2.protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private
-
3.private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private
但无论哪种继承方式,上面两点都没有改变:
-
1.private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;
-
2.protected 成员可以被派生类访问