学习c++ 第四天 类 及类的继承--class和struct的区别--static成员
Posted 蚁人日记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习c++ 第四天 类 及类的继承--class和struct的区别--static成员相关的知识,希望对你有一定的参考价值。
C++ 类
类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫类的实例化。每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数。
注意在类定义的最后有一个分号;
,它是类定义的一部分,表示类定义结束了,不能省略。
类只是一个模板(Template),编译后不占用内存空间,所以在定义类时不能对成员变量(除了声明变量外还可以定义方法)进行初始化,因为没有地方存储数据。只有在创建对象以后才会给成员变量分配内存,这个时候就可以赋值了。
创建对象以后,可以使用点号.
来访问成员变量和成员函数,这和通过结构体变量来访问它的成员类似
public 成员可以通过对象来访问,protected ,private 成员不能通过对象访问。
对象指针
通过对象名字访问成员使用点号.
,通过对象指针访问成员使用箭头->,(
this 只能用在类的内部,this 是一个指针,要用->
来访问成员变量或成员函数。而对象指针可以在类的外部引用成员变量或成员函数)
struct 结构体
C/C++ 允许数组定义可存储相同类型数据项的变量 ,如要存储不同类型的数据项则要使用到[ struct ]
struct struct_name
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
struct_object_names;
//如示例
struct Books
char title[50];
char author[50];
char subject[100];
int book_id;
book;
为了访问结构的成员,我们使用成员访问运算符(.)。与类的对象访问成员一样
类的继承(c++可以多继承,java 不是能多继承)
class 派生类名:[继承方式] 基类名
派生类新增加的成员
;
继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected(受保护的)。此项是可选项,如果不写,默认为 private(成员变量和成员函数默认也是 private)。
基类中的 protected 成员可以在派生类中使用,而基类中的 private 成员不能在派生类中使用,
1) public继承方式
- 基类中所有 public 成员在派生类中为 public 属性;
- 基类中所有 protected 成员在派生类中为 protected 属性;
- 基类中所有 private 成员在派生类中不能使用。
2) protected继承方式
- 基类中的所有 public 成员在派生类中为 protected 属性;
- 基类中的所有 protected 成员在派生类中为 protected 属性;
- 基类中的所有 private 成员在派生类中不能使用。
3) private继承方式
- 基类中的所有 public 成员在派生类中均为 private 属性;
- 基类中的所有 protected 成员在派生类中均为 private 属性;
- 基类中的所有 private 成员在派生类中不能使用。
通过上面的分析可以发现:
1) 基类成员在派生类中的访问权限不得高于继承方式中指定的权限。也就是说,继承方式中的 public、protected、private 是用来指明基类成员在派生类中的最高访问权限的。
2) 不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。
3) 如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些不希望在派生类中使用的成员才声明为 private。
4) 如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。
注意,我们这里说的是基类的 private 成员不能在派生类中使用,并没有说基类的 private 成员不能被继承。实际上,基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了。
多继承
//间接基类A
class A
protected:
int m_a;
;
//直接基类B
class B: public A
protected:
int m_b;
;
//直接基类C
class C: public A
protected:
int m_c;
;
//派生类D
class D: public B, public C
public:
void seta(int a) m_a = a; //命名冲突
void setb(int b) m_b = b; //正确
void setc(int c) m_c = c; //正确
void setd(int d) m_d = d; //正确
private:
int m_d;
;
int main()
D d;
return 0;
这段代码实现了上图所示的菱形继承,第 25 行代码试图直接访问成员变量 m_a,结果发生了错误,因为类 B 和类 C 中都有成员变量 m_a(从 A 类继承而来),编译器不知道选用哪一个,所以产生了歧义。
为了消除歧义,我们可以在 m_a 的前面指明它具体来自哪个类:
void seta(int a) B::m_a = a;
这样表示使用 B 类的 m_a。当然也可以使用 C 类的:
void seta(int a) C::m_a = a;
虚继承
为了解决多继承时的命名冲突和冗余数据问题,C++ 提出了虚继承,使得在派生类中只保留一份间接基类的成员。
在继承方式前面加上 virtual 关键字就是虚继承,请看下面的例子:
//间接基类A
class A
protected:
int m_a;
;
//直接基类B
class B: virtual public A //虚继承
protected:
int m_b;
;
//直接基类C
class C: virtual public A //虚继承
protected:
int m_c;
;
//派生类D
class D: public B, public C
public:
void seta(int a) m_a = a; //正确
void setb(int b) m_b = b; //正确
void setc(int c) m_c = c; //正确
void setd(int d) m_d = d; //正确
private:
int m_d;
;
int main()
D d;
return 0;
虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。其中,这个被共享的基类就称为虚基类(Virtual Base Class),本例中的 A 就是一个虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。
在C++中,struct 类似于 class,既可以包含成员变量,又可以包含成员函数。
C++中的 struct 和 class 基本是通用的,唯有几个细节不同:
- 使用 class 时,类中的成员默认都是 private 属性的;而使用 struct 时,结构体中的成员默认都是 public 属性的。
- class 继承默认是 private 继承,而 struct 继承默认是 public 继承
- class 可以使用模板,而 struct 不能
Static
在C++中,我们可以使用静态成员变量来实现多个对象共享数据的目标。静态成员变量是一种特殊的成员变量,它被关键字static修饰,
static 成员变量属于类,不属于某个具体的对象,即使创建多个对象,也只为static变量分配一份内存,所有对象使用的都是这份内存中的数据。当某个对象修改了static变量也会影响到其他对象,
static 成员变量必须在类声明的外部初始化,具体形式为:
type class::name = value;
type 是变量的类型,class 是类名,name 是变量名,value 是初始值。
静态成员变量在初始化时不能再加 static,但必须要有数据类型。被 private、protected、public 修饰的静态成员变量都可以用这种方式初始化。
static 成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在(类外)初始化时分配。反过来说,没有在类外初始化的 static 成员变量不能使用。static变量都在内存分区中的全局数据区分配内存,到程序结束时才释放。这就意味着,static 成员变量不随对象的创建而分配内存,也不随对象的销毁而释放内存。而普通成员变量在对象创建时分配内存,在对象销毁时释放内存。
static 成员变量既可以通过对象来访问,也可以通过类来访问。
//通过类Student 类访问 static 成员变量
Student::m_total = 10;
//通过对象来访问 static 成员变量
Student stu("小明", 15, 92.5f);
stu.m_total = 20;
//通过对象指针来访问 static 成员变量
Student *pstu = new Student("李华", 16, 96);
pstu -> m_total = 20;
static 成员变量不占用对象的内存,而是在所有对象之外开辟内存,即使不创建对象也可以访问(而this是必须在创建类对象之后才可能使用)
以上是关于学习c++ 第四天 类 及类的继承--class和struct的区别--static成员的主要内容,如果未能解决你的问题,请参考以下文章