Fork me on Github Fork me on Gitee

C++温故补缺(七):;类的访问控制和继承

类的访问控制和继承

类的静态成员

类的静态成员用关键字static修饰,类似静态变量或静态函数,也是有共享的概念

类的静态变量:

静态变量在类的所有对象中共享,不能再类的定义中初始化,但可以在类外部通过作用域符::来初始化,或通过对象初始化

class box{
    public:
        static int a;
};
int box::a=2;
int main(){
    box b1;
    cout<<b1.a;
}

静态变量也是有作用域的,需要public,调用时,只能通过对象调用,不能直接用类调用

静态成员函数:

类的静态成员函数可以直接被类调用,不需要初始化对象

class box{
    public:
        static void print(){};
};
int main(){
    box::print();
}

和普通成员函数的区别:

  • 静态成员函数没有this指针,只能访问静态成员

  • 而普通成员函数可以访问所有的,包括静态和非静态的成员

类中特殊成员变量的初始化:

  • const常量:必须通过构造函数参数列表初始化

  • 引用变量:必须通过构造函数参数列表初始化

  • 普通静态变量:要在类外通过::初始化

  • 静态整型常量:就是static const int,可以在定义的时候直接初始化

  • 静态非整型常量:要在类外通过::初始化

访问控制范围和继承范围

访问范围:

访问 public protected private
同一个类 yes yes yes
派生类 yes yes no
外部的类 yes no no

一个派生类继承所有基类的方法,除了:

  • 基类的构造函数,析构函数和拷贝构造函数

  • 基类的重载运算符

  • 基类的友元函数

  • 而且,派生类不能用初始化列表去初始化基类的成员,只能在函数体中初始化

继承范围:

继承方式 基类的public成员 基类的protected成员 基类的private成员
public继承 仍为public成员 仍为protected成员 不可见
protected继承 变为protected成员 变为protected成员 不可见
private继承 变为private成员 变为private成员 不可见

c++支持多继承:一个子类可以有多个父类

环状继承:A->D,B->D,C->A,B

这样的继承会使D创建两个对象,如:

#include<iostream>
using namespace std;

class box{
    public:
        box(){cout<<"create object"<<endl;};
};

class A:public box{};
class B:public box{};
class C:public A,public B{};
int main(){
    C c1;
}

要解决上面的问题就要用虚拟继承

格式:class 类名:virtual 继承方式 父类名

class A:virtual public box{};
class B:virtual public box{};
class C:public A,public B{};

上面说了,派生类不继承基类的构造函数,但是可以通过初始化列表调用基类的构造函数来初始化

#include<iostream>
using namespace std;

class box{
    public:
        int a;
        box();
        box(int a){this->a=a;};
};

class square:public box{
    public:
        square(int a):box(a){};
};
int main(){
    square s(23);
    cout<<s.a;
}

使用square(int a):box(a){};调用了基类的构造函数.

派生类继承的成员和本身的成员重名的话,不会覆盖或冲突,因为继承过来变量和本身的变量在不同的内存空间

如:

#include<iostream>
using namespace std;

class box{
    public:
        int a;
        void setA(int a){this->a=a;};
};

class square:public box{
    public:
        int a;
        void setAA(int a){this->a=a;};
};
int main(){
    square s;
    s.setA(10);
    s.setAA(20);
    cout<<s.box::a<<endl;
    cout<<s.square::a;
}

可以用作用域符::访问不同的同名变量

posted @ 2023-03-20 23:19  Tenerome  阅读(51)  评论(0编辑  收藏  举报