【足迹C++primer】53、访问控制和继承

访问控制和继承

public: 公有类型

private: 私有类型

protected: 保护类型

当一个类的成员定义为public,就能够在类外访问,包括它的派生类。

当一个成员定义为private,它仅能在类内访问,不能被它的派生类访问。

当一个成员定义为proteced,它仅能在类内访问,但是能被它的派生类访问。

当一个成员没有指定访问说明符时,默认为private。

派生类成员或友元可以访问受保护的成员

但只有只有通过派生类对象来访问。

class Base
{
protected:
    int prot_mem;
};

class Sneaky : public Base
{
    friend void clobber(Sneaky&);   //这个可以访问prot_mem
    friend void clobber(Base&);     //不能访问prot_mem,这个不是Base的友元
    int j;  //默认private类型
};

void clobber(Sneaky &s) {s.j=s.prot_mem=0; cout<<"通过Sneaky友元调用Base的prot_mem"<<endl;}

//void clobber(Base &b) {b.prot_mem=0;}   //error,prot_mem是保护的外面无法访问

public, private, and protected 继承

class Base2
{
    friend class Pal;
public:
    void pub_mem() {}
protected:
    int prot_mem;
private:
    char priv_mem;
};

struct Pub_Derv : public Base2
{
    int f() {return prot_mem;}
//    char g() {return priv_mem;} error:这个是private的无法访问
};

struct Priv_Derv : private Base2
{
    //私有继承不影响派生类中的访问,只是Base对于Priv_Derv来说都是private的
    int f() const {return prot_mem;}
};

void fun1()
{
    Pub_Derv d1;
    Priv_Derv d2;
    d1.pub_mem();
//    d2.pub_mem();   error:这里是私有继承,对于Priv_Derv来说Base2里面的类都是private类型的
}

struct Derived_from_public : public Pub_Derv
{
    int use_base(){return prot_mem;}    //ok:protected in pub_Derv
};

这里有一个错误示范~~~

struct Derived_from_private : public Priv_Derv
{
    int use_base(){return prot_mem;}    error:这里prot_mem是private类型
};

Friendship and Inheritance

友元函数可以访问该类的所有成员,但是没有访问该类派生类所有成员的权利

友元函数对于派生类来说就是在类的外部

class Base
{
    friend class Pal;
};
class Sneaky2 : public Base2
{
    int j;  //默认private类型
};

class Pal
{
public:
    int f(Base2 b) {return b.prot_mem;}
//    int f2(Sneaky s) {return s.j;}  error:Pal 不是Sneaky的友元
    int f3(Sneaky2 s2) {return s2.prot_mem;}    //不要惊讶,这是对的
};

class D2 : public Pal
{
public:
//    int mem(Base2 b){return b.prot_mem;}    error: 友元是无法继承的!!!

};

友元不是继承,每个类控制访问其成员,友元也不能继承。

Exempting Individual Members

class Base3
{
    friend class Pal;
public:
    size_t size() const {return n;}
    void pub_mem() {}
protected:
    size_t n;
    int prot_mem;
private:
    char priv_mem;
};

class Derved : private Base3
{
public:
    using Base3::size;  //用using改变访问权限
protected:
    using Base3::n;
};

用using 调整这些成员的访问权限

Default Inheritance Protection Levels(默认继承保护级别)

一个私人的派生类应明确指定私人而不是依靠

默认。明确表明私有继承的目的是

不要疏忽

the all code!

/**
* 功能:访问控制和继承
* 时间:2014年7月21日17:22:50
* 作者:cutter_point
*/

#include<iostream>
#include<algorithm>

using namespace std;
/*
public: 公有类型
private: 私有类型
protected: 保护类型
当一个类的成员定义为public,就能够在类外访问,包括它的派生类。
当一个成员定义为private,它仅能在类内访问,不能被它的派生类访问。
当一个成员定义为proteced,它仅能在类内访问,但是能被它的派生类访问。
当一个成员没有指定访问说明符时,默认为private。
*/

/*
派生类成员或友元可以访问受保护的成员
但只有只有通过派生类对象来访问。
*/
class Base
{
protected:
    int prot_mem;
};

class Sneaky : public Base
{
    friend void clobber(Sneaky&);   //这个可以访问prot_mem
    friend void clobber(Base&);     //不能访问prot_mem,这个不是Base的友元
    int j;  //默认private类型
};

void clobber(Sneaky &s) {s.j=s.prot_mem=0; cout<<"通过Sneaky友元调用Base的prot_mem"<<endl;}

//void clobber(Base &b) {b.prot_mem=0;}   //error,prot_mem是保护的外面无法访问

/**
public, private, and protected 继承
*/
class Base2
{
    friend class Pal;
public:
    void pub_mem() {}
protected:
    int prot_mem;
private:
    char priv_mem;
};

struct Pub_Derv : public Base2
{
    int f() {return prot_mem;}
//    char g() {return priv_mem;} error:这个是private的无法访问
};

struct Priv_Derv : private Base2
{
    //私有继承不影响派生类中的访问,只是Base对于Priv_Derv来说都是private的
    int f() const {return prot_mem;}
};

void fun1()
{
    Pub_Derv d1;
    Priv_Derv d2;
    d1.pub_mem();
//    d2.pub_mem();   error:这里是私有继承,对于Priv_Derv来说Base2里面的类都是private类型的
}

struct Derived_from_public : public Pub_Derv
{
    int use_base(){return prot_mem;}    //ok:protected in pub_Derv
};

/*
struct Derived_from_private : public Priv_Derv
{
    int use_base(){return prot_mem;}    error:这里prot_mem是private类型
};
*/

/**
Friendship and Inheritance
*/
/*
友元函数可以访问该类的所有成员,但是没有访问该类派生类所有成员的权利
友元函数对于派生类来说就是在类的外部
*/
/*
class Base
{
    friend class Pal;
};
*/

class Sneaky2 : public Base2
{
    int j;  //默认private类型
};

class Pal
{
public:
    int f(Base2 b) {return b.prot_mem;}
//    int f2(Sneaky s) {return s.j;}  error:Pal 不是Sneaky的友元
    int f3(Sneaky2 s2) {return s2.prot_mem;}    //不要惊讶,这是对的
};

class D2 : public Pal
{
public:
//    int mem(Base2 b){return b.prot_mem;}    error: 友元是无法继承的!!!

};

/*
友元不是继承,每个类控制访问其成员
*/

/**
Exempting Individual Members
*/
class Base3
{
    friend class Pal;
public:
    size_t size() const {return n;}
    void pub_mem() {}
protected:
    size_t n;
    int prot_mem;
private:
    char priv_mem;
};

class Derved : private Base3
{
public:
    using Base3::size;  //用using改变访问权限
protected:
    using Base3::n;
};

/*
用using 调整这些成员的访问权限
*/

/**
Default Inheritance Protection Levels(默认继承保护级别)
*/

/*
一个私人的派生类应明确指定私人而不是依靠
默认。明确表明私有继承的目的是
不要疏忽
*/

int main()
{

    system("pause");
    return 0;
}

人的贬值,不是年龄的贬值,是自我身价与姿态的贬值;一个人的衰老不是容颜的衰老,是进取心的衰老。一个人的不自信,不是自卑心作怪,是过于贬低自己不相信自己:其实我可以不依靠别人做的会更好。岁月会告诉我们很多事,长得好没太大青春资本,人的资本是自身的历练和能力。

我觉得可以给大家一点有点意思的句子,说着无心,听者有意,也许有一句就是适合你,属于你,并且激励着你!!!

【足迹C++primer】53、访问控制和继承

时间: 2024-11-17 12:54:12

【足迹C++primer】53、访问控制和继承的相关文章

【足迹C++primer】54、继承类的范围,构造函数和拷贝控制

继承类的范围,构造函数和拷贝控制 当用派生类执行函数的时候,首先会在当前的类里面找 如果找不到就一级一级地往上找. Name Lookup Happens at Compile Time class Quote { public: Quote()=default; Quote(const string &book, double sales_price):bookNo(book), price(sales_price) {cout<<"Quote gouzhao functi

【足迹C++primer】表达式求值

表达式求值 /** * 功能:表达式求值(0到9) * 时间:2014年6月15日08:02:31 * 作者:cutter_point */ #include<stdlib.h> #include<stack> #include<iostream> #include<string> using namespace std; stack<int> intStack; //存放数值的栈 stack<char> charStack; //存

【足迹C++primer】56、文本查询程序

/** * 功能:文本查询程序 * 时间:2014年7月23日10:26:09 * 作者:cutter_point */ #include<iostream> #include<algorithm> #include<memory> #include<set> #include<map> #include<fstream> #include<sstream> using namespace std; /* Alice Em

【足迹C++primer】22、文件输入输出

文件输入输出 使用文件流对象 创建文件流对象时,我们可以提供文件名(可选).如果提供了一个文件名,则open会自动被调用: ifstream in(ifile); //构造一个ifstream并打开给定文件 ofstream out; //输出文件流未关联到任何文件 用fstream代替iostream& 首先这里有一个头文件和一个定义的文件要使用 Sales_data.h #ifndef SALES_DATA_H_INCLUDED #define SALES_DATA_H_INCLUDED #

OOP2(虚函数/抽象基类/访问控制与继承)

通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当某个虚函数通过指针或引用调用时,编译器产生的代码直到运行时才能确定应该调用哪个版本的函数.被调用的函数是与之绑定到指针或引用上的对象的动态类型相匹配的那一个 注意:动态绑定只有当我们通过指针或引用调用虚函数时才会发生.当我们通过一个具有普通类型(非引用非指针)的表达式调用虚函数时,在编译时就会将调用

面向对象程序设计——抽象基类,访问控制与继承,继承中的类作用域,拷贝函数与拷贝控制

一.抽象基类 1)纯虚函数 和普通的虚函数不同,一个纯虚函数无须定义.我们通过在函数体的位置(即在声明语句的分号之前)书写=0就可以将一个虚函数说明为纯虚函数.其中,=0只能出现在类内部的虚函数声明语句处. 值得注意的是,我们也可以为纯虚函数提供定义,不过函数体必须定义在类的外部.也就是说,我们不能在类的内部为一个=0的函数提供函数体. 2)含有纯虚函数的类是抽象基类 含有(或者未经覆盖直接继承)纯虚函数的类是抽象基类.抽象基类负责定义接口,而后续的其他类可以覆盖该接口.我们不能直接创建一个抽象

【足迹C++primer】38、关联容器操作(2)

关联容器操作(2) map的下标操作 map的下标操作 map和unordered_map容器提供了下标运算符合一个对应的at函数 对于一个map使用下标操作,其行为与数组或vector上的下标操作很不相同: 使用一个不再容器中的关键字作为下标,会添加一个此关键字的元素到map中 map和unordered_map的下标操作 c[k] 返回关键字为k的元素,如果关键字k不再c中,添加一个关键字为k的元素,对其进行值初始化 c.at(k) 访问关键字为k的元素,带参数检测,如果k不再c重那么返回一

【足迹C++primer】27、vector对象是如何增长的

vector对象是如何增长的 当需要更多空间的时候,会重新分配比新空间需求更大的内存空间,作为备用 管理容器的成员函数 shrink_to_fit //只适用于vector,string,deque capacity reserve //只适用于vector,string c.shrink_to_fit() //请将capacity()减少为与size相同大小 c.capacity() //不重新分配内存空间的话,c可以保存多少元素 c.reserve(n) //分配至少能容纳n个元素的内存空间

【足迹C++primer】41、文本查询程序

/** * 功能:使用标准库:文本查询程序 * 时间:2014年7月10日09:10:15 * 作者:cutter_point */ #include<iostream> #include<map> #include<set> #include<fstream> #include<sstream> #include<string> #include<vector> #include<memory> using