类
【1】关于类的知识点有哪些?
理解类从以下几个方面:
(1)类(class)实际上是对某种类型的对象定义属性和方法的原型。
它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础。
那么抽象怎么理解?比如,“水果”这个词就很抽象,“人民”这个词也很抽象,“动物”这个词同样抽象。咋这么说呢?
你试着想想:有人让你去给她买二斤水果,你肯定要问买什么水果,到底是苹果?香蕉?梨?桔子?......... 你说它叫得多抽象呀~
(2)类是对某个对象的定义。它包含有关对象动作方式的信息,包括它的属性和方法。实际上它本身并不是对象,因为它不存在于内存中。
也就是说:实实在在是不存在它这样的一个实物的!当使用类的代码运行时,内存中会创建类的一个实例,即对象。
虽然只有一个类,但能由这个类在内存中创建多个相同类型的对象,只是彼此属性不同,而方法或者说事件是完全相同的。
(3)属性是区别彼此的变量集;方法是此类对象共有的一种能力或者说功能的函数。
(4)可以把类看作“理论上”的对象,也就是说,它为对象提供蓝图 ,但在内存中并不存在。
从这个蓝图可以创建任何数量的对象。从类创建的所有对象都有相同的成员:属性、方法和事件。
但是,每个对象都像一个独立的实体一样。例如,一个对象的属性可以设置成与同类型的其它对象完全不同的值。
(5)类的定义形式
示例代码如下:
类的定义由类头 和 类体 两部分组成。
类头由关键字Class 开头,然后是类名,其命名规则与一般标识符的命名规则一致。
类体包括所有的细节,并放在一对花括号中。
类的定义也是一个语句,所以要以分号结尾,否则会产生编译错误。
(6)类体分为两种成员
<1>类的数据成员,即就是属性变量
<2>类的成员函数,即就是功能方法
(7)类中成员的有三种访问权限
<1> private:私有的
该类成员只可以被该类的成员函数访问
<2> public: 公有的
该类成员可以在类外访问
<3> protected: 受保护的
该类成员只能被此类的成员函数或派生类的成员函数访问
(8)类的定义和使用注意点
<1> 在类的定义中,不能对数据成员进行初始化
<2> 类的所有成员都有访问属性,即使没有标注的情况下,系统默认是私有的【class关键字的前提下】
<3> 一般将数据成员定义为私有成员或者保护成员,而将成员函数定义为共有成员
<4> 类中的数据成员可以是C++语法中的任意类型,但是不能用存储类型auto,register或者extern修饰
<5> 一个类的成员可以是其他类的对象,但是不能以类自身的对象作为类的成员,而类自身的指针或引用可以作为类的成员
<6> 在C语言中,结构只有数据成员。
在C++中struct关键字也可以定义类,与class的最大区别是其成员默认的属性为public,而class成员的默认属性是private
<7> 每个类都定义了自己的新作用域和唯一的类型
<8> 类的定义以分号结束。一则:整个定义是一个完整的语句;二则:其后可以直接接一个对象列表
<9> 成员函数定义在类的内部,相当于内联函数;如果定义在类的外部,需要实现内联函数,必须要显式加入inline关键字
<10> 类的外部定义成员函数形式如下:类名::函数名(){.......}
(9)类的定义数据成员示例代码如下:
1 class Test
2 {
3 private:
4 int value; //一般数据成员
5 static int num; //静态成员(类外初始化)
6 const int max; //常量成员(参数列表初始化)
7 static const int min; //静态常量(类外初始化)
8 int &b; //一般引用(参数列表)
9 int *p; //一般指针成员
10 //Test t1; //error!!!! 自身对象(无限递归)
11 static Test t; //自身静态对象
12 Test &t2; //自身引用
13 Test *t3; //自身指针
14 };
(10)由类定义分析类创建对象占用内存大小
关于类占用的内存大小问题,是每个程序员值得慎重考虑的。
那么在平时的学习中,我们就应该有这方面的意识。
下面仅仅就自己的总结分析一部分,因为暂不牵涉内存对齐的情况。
示例代码如下:
1 #include<iostream> 2 using namespace std; 3 4 class A 5 {}; 6 // 空类,因为(为什么?请参见随笔《类的认识》)编译器会用一个字节标记这个类,所以大小为1 7 8 class B : public A 9 {}; 10 // B继承于A,但同样也是空类,大小仍为1 11 12 class C : virtual public A 13 {}; 14 // C虚继承于A,编译器会为其添加一个指向基类的指针,所以大小变为4 15 16 class D 17 { 18 public: 19 int a; 20 static int b; // 静态变量被放在静态存储区 21 }; 22 // 静态变量存储位置不同不占用类的内存空间,所以大小为4 23 24 class E 25 { 26 public: 27 void print() { cout << "E" << endl; } 28 29 private: 30 int a; 31 }; 32 // 成员函数不占类的内存空间,所以大小仍为4 33 34 class F 35 { 36 public: 37 int a; 38 const int b; // 常量成员(参数列表初始化) 39 F() : a(1), b(2) 40 {} 41 }; 42 // 常量成员占用类的内存空间,所以大小为8 43 44 class G 45 { 46 public: 47 int a; 48 static const int b; //静态常量成员(类外初始化) 49 }; 50 const int G::b = 10; 51 // 静态常量成员存储位置不同,不占用类的内存空间,所以大小为4 52 53 class H 54 { 55 public: 56 int a; 57 int &b; // 引用变量成员(参数列表初始化) 58 H() : a(1), b(a) 59 {} 60 }; 61 // 引用变量成员占用类的内存空间,所以大小为8 62 63 class I 64 { 65 public: 66 int a; 67 static I b; 68 }; 69 // 自身静态成员对象(即静态变量,同类D)不占用类的内存空间,所以大小为4 70 71 class J 72 { 73 public: 74 int a; 75 J *p; 76 }; 77 // 自身指针变量占用类的内存空间,所以大小为8 78 79 class K 80 { 81 int a; 82 83 public: 84 static void Fun() 85 { 86 cout << "Fun" << endl; 87 } 88 }; 89 // 类的静态成员函数也不占用类的内存空间,所以大小为4 90 91 class L 92 { 93 public: 94 virtual void print() { cout << "F" << endl; } 95 96 private: 97 int a; 98 }; 99 // 一旦有虚函数就会多一个虚表指针,系统需要用这个指针维护虚函数表。所以大小为8 100 101 class M : public L 102 { 103 public: 104 int b; 105 virtual void print() { cout << "G" << endl; } 106 virtual void print2() { cout << "G2" << endl; } 107 }; 108 // 至于多几个虚函数不会影响内存大小变化。可见一个类只有一个虚函数指针。大小为12 109 110 void main() 111 { 112 A a; 113 B b; 114 C c; 115 D d; 116 E e; 117 F f; 118 G g; 119 H h; 120 I i; 121 J j; 122 K k; 123 L l; 124 M m; 125 cout << "A:" << sizeof(A) << " " << sizeof(a) << endl; //1 1 126 cout << "B:" << sizeof(B) << " " << sizeof(b) << endl; //1 1 127 cout << "C:" << sizeof(C) << " " << sizeof(c) << endl; //4 4 128 cout << "D:" << sizeof(D) << " " << sizeof(d) << endl; //4 4 129 cout << "E:" << sizeof(E) << " " << sizeof(e) << endl; //4 4 130 cout << "F:" << sizeof(F) << " " << sizeof(f) << endl; //8 8 131 cout << "G:" << sizeof(G) << " " << sizeof(g) << endl; //4 4 132 cout << "H:" << sizeof(H) << " " << sizeof(h) << endl; //8 8 133 cout << "I:" << sizeof(I) << " " << sizeof(i) << endl; //4 4 134 cout << "J:" << sizeof(J) << " " << sizeof(j) << endl; //8 8 135 cout << "K:" << sizeof(K) << " " << sizeof(k) << endl; //4 4 136 cout << "L:" << sizeof(L) << " " << sizeof(l) << endl; //8 8 137 cout << "M:" << sizeof(M) << " " << sizeof(m) << endl; //12 12 138 139 system("pause"); 140 }
希望有所收获。