zoukankan      html  css  js  c++  java
  • 访问控制 : public、private、protected以及friend

    https://blog.csdn.net/Tostick/article/details/80685482 

    public  所有均可访问
    private 类自己的成员函数访问,不能被类对象访问

    protected 类自己以及子类访问,不能被类对象访问

    friend 友元,别人是你的朋友,他可以访问我的东西。(但不是我可以访问他的东西)

    友元关系不能被继承。
    友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
    友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明 
    友元函数并不是类的成员函数,因此在类外定义的时候不能加上class::function name
    例子1 

    #include <iostream>
    using namespace std;
    
    class A {
    private:
    int i;
    public:
    A() {i = 0; cout <<"A::A"<<endl; }
    ~A() {i = 0; cout <<"A::~A"<<i<<endl; }
    void set(int i) {this->i = i;}
    void g(A *q) { cout << q->i << endl; }
    };
    
    int main ()
    {
    A a;
    A b;
    b.set(100);
    a.g(&b); // 使用对象a的成员函数访问对象b中的私有变量i,则不能通过对象直接访问
    return 0;
    }

    结果

     

    备注:

    private,protected限制编译时刻检查,而不是运行检查。一直编译成二进制,则不再受到此限制。
    struct 缺省权限是public, class缺省权限是private
    C++中,只有成员变量很简单数量少才可能使用struct;一般使用class


    例子2-protected

    #include <iostream>
    using namespace std;
    
    class A {
    public:
    int a = 1;
    private:
    int b = 2;
    protected:
    int c = 3;
    };
    
    class B: public A
    {
    public:
    void func()
    {
    std::cout << A::a << std::endl; // 可通过A类访问公有变量
    // std::cout << A::b << std::endl; // 不能在B类中通过A类访问私有变量
    std::cout << A::c << std::endl; // 可通过A类访问保护变量
    }
    };
    
    int main()
    {
    B b;
    A a;
    cout << b.a << a.a << endl; // 可通过A类变量访问共有变量
    // cout << b.c << a.c << endl; // 不可通A过类变量访问保护变量
    return 0;
    }

    注:

    类中省略public 等时,默认是private属性
    继承基类, 在基类前省略public 等时, 默认是protected属性

     例子3-友元函数,外部调用可访问类的变量和方法

    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    class Point
    {
    public:
    Point(double xx, double yy) { x=xx; y=yy; } //默认构造函数
    void Getxy(); //公有成员函数
    friend double Distance(Point &a, Point &b); //友元函数
    private:
    double x, y;
    int key = 101;
    public:
    int kk = 102;
    };
    
    void Point::Getxy()
    {
    cout<<key<<endl; // 函数定义中访问私有变量
    }
    
    double Distance(Point &a, Point &b) // 友元定义,注意函数名前未加类声明符
    {
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx*dx+dy*dy);
    }
    
    int main()
    {
    Point p1(3.0, 4.0), p2(6.0, 8.0);
    p1.Getxy();
    
    // cout << p2.key << endl; 不能访问私有变量
    // cout << Point::key << endl; 不能访问非静态变量
    
    cout << p2.kk << endl;
    double d = Distance(p1, p2); // 友元访问
    cout<<"Distance is: "<<d<<endl;
    
    return 0;
    }

    结果:

     

    例子4-友元类,外部调用可访问类的变量和方法
    当一个类作为另一个类的友元时,它的所有成员函数都是另一个类的友元函数,都可以访问另一个类的私有或者公有成员

    友元作为参数与使用类指针作为参数的区别在于,友元可以访问类的私有成员

    #include <iostream> 
    #include <cstring> 
    using namespace std ; 
    //声明教师类 
    class Techer ; 
    //学生类 
    class Student 
    { 
    private: 
    string name ; 
    int age ; 
    char sex ; 
    int score ; 
    public : 
    Student(string name , int age , char sex , int score); 
    void stu_print(Techer &tech); 
    }; 
    //教师类 
    class Techer 
    { 
    private: 
    string name ; 
    int age ; 
    char sex ; 
    int score ; 
    public : 
    Techer(string name , int age , char sex , int score); 
    //声明一个友元类 
    friend Student ; 
    }; 
    
    //Student类的构造函数的实现 
    Student::Student(string name , int age , char sex , int score) 
    { 
    this->name = name ; 
    this->age = age ; 
    this->sex = sex ; 
    this->score = score ; 
    } 
    //Techer类的构造函数的实现 
    Techer::Techer(string name , int age , char sex , int score) 
    { 
    this->name = name ; 
    this->age = age ; 
    this->sex = sex ; 
    this->score = score ; 
    } 
    
    //打印Student类中的私有成员和Techer的私有成员 
    void Student::stu_print(Techer &tech) 
    { 
    //用this指针访问本类的成员 
    cout << this->name << endl ; 
    cout << this->age << endl ; 
    cout << this->sex << endl ; 
    cout << this->score << endl ; 
    //访问Techer类的成员 
    cout << tech.name << endl ; 
    cout << tech.age << endl ; 
    cout << tech.sex << endl ; 
    cout << tech.score << endl ; 
    } 
    
    int main(void) 
    { 
    Student stu1("YYX",24,'N',86); 
    Techer t1("hou",40,'N',99); 
    stu1.stu_print(t1); 
    return 0 ; 
    }

    结果

     

    备注:

    运算符重载经常使用friend
    friend写在类声明中,一旦类实现完成,则不能再添加friend
    friend的授权在编译期

    ---------------------
    作者:gocgocgo
    来源:CSDN
    原文:https://blog.csdn.net/Tostick/article/details/80685482
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调
    Android OpenSL ES 开发:Android OpenSL 录制 PCM 音频数据
    Android MediaPlayer SeekTo 在 8.0 版本上优化说明
    Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明
    Android NDK学习(七):NDK 编译支持 C++特有的库
    Hystrix浅谈
    RxJava
    Metrics介绍和Spring的集成
    Hystrix系列-5-Hystrix的资源隔离策略
    深度解析SpringMvc实现原理手写SpringMvc框架
  • 原文地址:https://www.cnblogs.com/wllwqdeai/p/10111775.html
Copyright © 2011-2022 走看看