[C++] OOP

摘要:
访问控制和继承受保护的成员类似于私有,受保护的会员不可供类别的成员访问类似于公共,受保护会员可供来自该类别的成员和朋友访问。会员

Access Control And Inheritance

Protected Member

Like private, protected members are unaccessible to users of the class

Like public, protected members are accessible to members and friends of classes derived from this class.

Members and friends of a derived class can access the protected members only on the base class that are embeded inside the derived type object; they have no special access to a ordinary object of the base class.

classBase{
protected:
    intprot_item;
};
class Sneaky : publicBase{
    friend void clobber(Sneeky &);
    friend void clobber(Base &);
    intj;
};
void clobber(Sneaky & s) { s.prote_item =0;}    //ok
//error: clobber cannot access the protect member in Base;
void clobber(Base & b) { b.prot_item = 0;}    

public, private and protect inheritance

classBase{
public:
    voidpub_mem();
protected:
    intprot_mem;
private:
    charpriv_mem;
}
struct Pub_Derv : publicBase{
    //ok. derived class can access protected members
    int f() { returnprot_mem; }
    //error. private members are inaccessible to derived class
    char g() { returnpriv_mem; }
}
struct Priv_Derv : privateBase{
    //private derivation do not affect access in the derived class
    int f1() { return prot_mem; } //ok
    char g2() {return priv_mem; } //error
}

The derivation access specifier have no effect on whether a member of derived class may access to the members of its own direct base class. Access to the members of the base class is conrolled by the access specifer in the base class itself.

Both Pub_Deriv and Priv_Derv have access to the protected member prot_mem. Neither of them may access the private member Priv_mem.

The derivation access specifier is to control the access that users of the derived class - including other classed derived from the derived class - have to the members inherited from base.

    Pub_Derv d1;    //members inherited from Base remain the same access specifer
    Priv_Derv d2;    //members inherited from Base are private
    d1.pub_mem();    //ok. pub_mem is public in the derived class
    d2.pub_mem();    //error. pub_mem is private in the derived class

The derivation access specifier used by the derived class also control the access from classed that inherited from the derived class.

struct Drived_from_public : publicPub_Derv{
    //ok. Base::prot_mem remain protected in Pub_Derv
    int use_base(){ returnprot_mem; }
};
struct Derived_from_private : publicPriv_Derv{
    //error. Base::prot_mem is private in Priv_Derv
    int use_base() { returnprot_mem; }
};

Had we defined another class, say, Prot_Derv, that use protected inheritance, the public members of base would be protected members in that class. Users of prot_Derv would have no access to Pub_mem, but members and friends of Prot_Derv have access to the inherited members.

Assumig D inherits from B.

User code may use the derived-to-base conversion only if D inherits publicly from B. User code may not use the conversion if D inherits from B using either protected or private.

An implementation member should be protected if it provides operation or data that a derived class will use in its own implementation. Otherwise, implementation member should be private.

friendship and inheritance

Just as friendship is not transitive, friendship is also not inherited.

Friends of the base type have no special access to the members of the derived class. Friends of the derived type also have no special access to the members of the base type.

classBase{
    //remain other members as before
    friend classpal;
};
classPal{
public:
    int f(Base b) { return b.prot_mem; }  //ok
    int f2(Sneaky s) { return s.j; }    //error. Pal is not friend of Sneaky
    int f3(Sneaky s) { return s.prot_mem; } //ok!!!
}

The fact that f3 is legal may be surprising, but it follows the notion that each class controls access to its own members. Pal is a friend of Base. So it also have access to the Base object that embeded in an object of type derived from Base.

Tony: when a friend of a base type access to a member through the derived class of the base type, need to consider 1)whether this member is inherited from the base, 2) if yes, the actual access level of the member in the base type.

When a class make another class a friend, it is only that class to which friendshp is granted. The base class class of, and the derived class from, the friend have no special access to the members of the befriending class.

class D2 : publicPal{
public:
    //error. friendship is not inherited.
    int mem(Base b) { returnb.prot_mem; }
};

Exempting Individual Members

Sometimes we need to change the access level to a mambers that a class inherits. We can do so by providing a using declaration.

classBase{
public:
    size_t size() const { returnn; }
protected:
    size_t n;
};
class Derived : privateBase{
public:
    usingBase::size;
protected:
    usingBase::n;
};

Tony: private derivation do not support implicit derived-to-base conversion; then it also do not support polymorphism. So, privevation derivation is not a common use in OOP. The effective use of changing access level to members in C++ is similar to that in Java.

Class Scope under Inheritance

class Disc_quote: publicQuote{
public:
    pair<size_t, double> discount_policy const{ 
        return{quantity, discount}; 
    }
    //other members as before
};
Bulk_quote bulk;
Bulk_quote * bulkP = &bulk;    //static and dynamic type are the same
Quote * itemP = & bulk;    //static andy dynamic type differ
bulkP->discount_policy();    //ok
itemP->discount_policy();    //error itemP has type Quote*

Even though bulk has the member named discount_policy, that members is not visible to through itemP. The type of itemP points to Quote, which means that the search for discount_policy start in class Quote.

Bulk_quote bulk;
    cout << bulk->isbn();

The use of the isbn is resolved as follow:

Because we call isbn on an object of Bulk_quote, the research start in Bulk_quote. The name isbn is not found in that class.

Because Bulk_quote is derived from Disc_quote, the Disc_quote is searched next. The name isbn is not found.

Because Disc_quote is derived from Quote, The Quote is searched next. The name isbn is found in that class, the use of isbn is resolved to the isbn in Quote.

As usual, names defined in the inner scope(e.g. a derived class) hides the same names of outer scope(e.g. the base class).

We can use a hidden base-class memer by scope operator:

structDerived : Base{
    int get_base_mem() { returnBase::mem; }
    //...
};

Aside from overriding inherited virtual function, a derived class should not reuse the names defined in its base class.

Functions defined in a derived class do not override members defined in its base class. If a memebers in a derived class has the same name as the base member, then the base member is hidden even if they have different parameter list

structBase{
    intmemfcn();
};
structDerived : Base{
    int memfcn(int);    //hides memfcn in the base
};
Base b;
Derived d;
b.memfcn();
d.memfcn(31);
d.memfcn();    //error: memfcn with no argument is hidden
d.Base::memfcn();    //ok 

To resolve this call, look for name memfcn in Derived. The name is found, then compiler stop further search. The version of memfcn in Derived expected an int argument. This call provide no argument; it is in error.

classD1{
public:
    int fcn(int);
};
class D2 : publicD1{
public:
    int fcn(int);    //nonvirtual function hide D1::fcn(itn)
};
D2 d2Obj;
D1 *p1 = &d2Obj;
D2 *p2 = &d2Obj;
p1->fcn(41);    //statically bound, call D1::fcn(int)
p2->fcn(41);    //statically bound, call D2::fcn(int)

When we call an nonvirtual function, the version that is called depends only on the static type of the object. The dynamic type is ignored.

Override Overload Functions

If a derived class want to make ll overload functions of base available through its type, then it must override all of them or non of them.

Instead of Override every base class version that it inherits, a derived class can provide using declaration for the overload function. A using declaration only specifier a name. Thus, using declaration for a base members adds all instances of the overload function into the scope of the derived class.

Reference:

C++ Primer, Fifth Edition, chapter 15 Object-Oriented Programming

免责声明:文章转载自《[C++] OOP》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇svnjs获取节点下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

VLAN、Trunk,以太通道及DHCP

VLAN、Trunk,以太通道及DHCP 案例1:Vlan的划分 案例2:配置trunk中继链路 案例3:以太通道配置 案例4:DHCP服务配置 1 案例1:Vlan的划分 1.1 问题 VLAN(虚拟局域网)是对连接到的第二层交换机端口的网络用户的逻辑分段,不受网络用户的物理位置限制而根据用户需求进行网络分段。一个VLAN可以在一个交换机或者跨交换机...

微信公众平台开发——微信授权登录(OAuth2.0)

1、OAuth2.0简介   OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。   允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2...

开放平台鉴权以及OAuth2.0介绍

OAuth 2.0 协议 OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容。 OAuth 2.0不兼容1.0。 协议的参与者 RO (resource owner): 资源所有者,对资源具有授权能力的人。 RS (resource server...

Nginx 配置按日期每天生成一个日志文件

百度了几个配置方法,只有一个成功了,记录下。 1. 先设个变量$logdate map $time_iso8601 $logdate { '~^(?<ymd>d{4}-d{2}-d{2})'$ymd; default 'date-not-found'; } 上面这段放到 http 块,我用的宝塔面板,在nginx管理里修改...

Facebook应用程序权限请求以及数据获取

最近因工作需要研究了一下facebook的API调用. 虽然是一个不存在的网站,但也是工作内容的一部分,需要认真对待.既然对于咱们国人来说不存在,当然也就没有汉字可看了.英文文档让我头晕了好一阵子,吐了好几次之后终于摸清了脉络. 大致步骤是: 1、创建一个应用程序,可以获得App ID/API Key和App Secret。 2、使用URL: https:...

CORS跨域实现思路及相关解决方案

本篇包括以下内容: CORS 定义 CORS 对比 JSONP CORS,BROWSER支持情况 主要用途 Ajax请求跨域资源的异常 CORS 实现思路 安全说明 CORS 几种解决方案 自定义CORSFilter Nginx 配置支持Ajax跨域 支持多域名配置的CORS Filter keyword:cors,跨域,ajax,403,fi...