zoukankan      html  css  js  c++  java
  • [C++]访问控制与继承(public,protect,private)

    C++有三种访问控制符号:public,protect,private,

    同时,也有三种继承方式:public,protect,private。

    访问控制

    访问控制是对类成员而言的,对非类成员而言,访问控制是不适用的。

    在Java,C#中,也有访问控制的概念,不过Java和C#中,访问控制的用法与C++不用:

    class Foo
    {   // C++支持这种形式
    public:
        int a;
    };
    
    class Foo
    {   // C#支持这种形式
        public int a;
    }
    

    public

    木有任何限制

    private

    只能被类声明中的成员函数和友元访问。

    注意~这里是“类声明中”而不是“实例中”,同一个类的不同实例,是可以互访private成员的,下文的protect也类似:

    #include <iostream>
    
    class Foo
    {
    private:
        int _val;
    public:
        Foo(int val): _val(val){};
        int GetValue(Foo& foo)
        {   // 访问private成员
            return foo._val;
        }
    };
    int main(void)
    {
        Foo foo1(1);
        Foo foo2(2);
        std::cout << foo1.GetValue(foo1) << std::endl;
    // foo1访问了foo2的private成员,跨实例访问 std::cout << foo1.GetValue(foo2) << std::endl; }

    private的另一个用途是禁用编译器自动生成的代码。对于一个类,编译器自动构造3个玩意:

    默认构造函数、默认复制构造函数、默认赋值函数,如果不想让编译器生成这3个玩意,需要显式将之设置为private属性~:

    #include <iostream>
    
    class FooA
    {
    public:
        int value;
    };
    
    int main(void)
    {
        using namespace std;
        // 调用了编译器生成的默认构造函数
        FooA fooA1;
        
        fooA1.value = 5;
        // 调用了编译器默认生成的复制构造函数
        FooA fooA2 = fooA1;
    
        fooA1.value = 10;
        FooA fooA3;
        // 调用了编译器默认生成的赋值函数
        fooA3 = fooA1;
    
        cout << fooA1.value << fooA2.value << fooA3.value << endl;
        system("pause");
    }
    
    #include <iostream>
    
    class FooB
    {
    public:
        int value;
        FooB(int v):value(v){};
    // 通过private禁用了以下3个玩意
    private:
        FooB();
        FooB(FooB&);
        FooB& operator=(FooB&);
    };
    
    int main(void)
    {
        using namespace std;
        // 禁用了默认构造函数:
        // error C2248: “FooB::FooB”: 无法访问 private 成员(在“FooB”类中声明)
        // FooB fooB1;
        FooB fooB1(0);
    
        fooB1.value = 5;
        // 禁用了复制构造函数
        // error C2248: “FooB::FooB”: 无法访问 private 成员(在“FooB”类中声明)
        // FooB fooB2 = fooB1;
    
        fooB1.value = 10;
        FooB fooB3(0);
        // 禁用了赋值运算符
        // error C2248: “FooB::operator =”: 无法访问 private 成员(在“FooB”类中声明)
        // fooB3 = fooB1;
    
        //cout << fooB1.value << fooB2.value << fooB3.value << endl;
        system("pause");
    }
    

    protect

    如果不考虑继承,protect和private完全一样。但是在继承中,protect就有了各种奇葩的表现。

    继承访问控制

    在继承中,可以指定继承方式,继承方式和上述的访问控制相结合,用以派生类中基类成员的访问控制。

    继承访问控制和基类成员的访问控制的结合,有如下规律——“从严控制”,显然,由宽松至严格的顺序为:
    public>protect>private

    public继承

    最宽松的继承,基类成员的访问控制不变~

    protect继承

    基类的

  • 相关阅读:
    线性变换 矩阵
    【安全】安全测试基本切入点
    【产品】汉语言基础对产品经理的重要性
    【Selenium】自动化调试后C盘越来越大
    【记录】让人淡疼的BUG之参数传送错误
    【转载】Java 升级到jdk7后DbVisualizer 6 启动空指针的处理方案
    cocoapods 报错
    mac 版 Pycharm 激活
    Foxmail添加gmail密码错误
    Apple 相关官方地址
  • 原文地址:https://www.cnblogs.com/SelaSelah/p/2634256.html
Copyright © 2011-2022 走看看