08.2.4读书笔记

一.友元

 友元提供了访问类的私有数据成员的机制

#include  < iostream >

using   namespace  std;

class  c2;
class  c1
{
    
int i;
public:
    
void set(int j){i=j;}
    
bool allzero(c2);
}
;

class  c2
{
    
int i;
public :
    
void set(int j){i=j;}
    friend 
bool c1::allzero(c2);
}
;

bool  c1::allzero(c2 c)
{
    
if(this->i==0 && c.i==0)
        
return true;
    
return false;
}


int  main()
{
    c1 cx;
    c2 cy;
    cx.
set(0);
    cy.
set(0);
    
if(cx.allzero(cy))
        cout
<<"all zero"<<endl;
    
return 0;
}

 

2.友元运算符重载

对于operator+,两种重载方式:

 

three_d three_d:: operator - (three_d t)
{
  three_d temp;
  temp.x
=x-t.x;
  temp.y
=y-t.y;
  
return temp;
}

对于上述的这种方式,a=a+10可以运行,但a=10+a不行.

three_d three_d:: operator - (three_d t1,three_d t2)
{
  three_d temp;
  temp.x
=t1.x-t2.x;
  temp.y
=t1.y-t2.y;
  
return temp;
}

对果用两个友元函数来重载+,则上述问题可以避免.一种是+运算符函数处理对象+函数,另一种运算符处理"整数+对象".使用友元重载+(或其他二元操作数)允许内建类型出现于运算符的左边或右边.

二.访问权限的控制

1.public,private,protected

第一:private,public,protected方法的访问范围.
private: 只能由该类中的方法访问,不能被该类的对象访问.
protected: 可以被该类中的方法和其友元函数访问,但不能被该类的对象访问
public: 可以被该类中的方法和其友元函数访问,也可以由该类的对象访问
第二:类的继承后方法属性变化:
使用private继承,父类的所有方法在子类中变为private;
使用protected继承,父类的protected和public方法在子类中变为protected,private方法不变;
使用public继承,父类中的方法属性不发生改变;

基类的public成员能够被程序中所有函数访问,private成员只能被基类的成员函数和友元访问。protected访问是public访问和private访问之间的中间层次。基类的protected成员只能被基类的成员和友元以及派生类的成员和友元访问。派生类成员简单地使用成员名就可以引用基类的public成员和protected成员。注意protected数据破坏了封装,基类protected成员改变时,所有派生类都要修改。

公有派生类的对象可作为其相应基类的对象处理,这使得一些有意义的操作成为可能。例如,从某个特定基类派生出来的各种类,尽管这些类的对象彼此之间互不相同,但是仍然能够建立这些对象的链表,只要把这些对象作为基类对象处理就可以了。然而反过来是不行的,基类的对象不能自动成为派生类的对象。

三.构造函数,析构函数的调用顺序.

#include  < iostream >

using   namespace  std;

class   base
{
public:
    
base(){cout<<"base constructor"<<endl;}
    
~base(){cout<<"base destructed"<<endl;}
}
;

class  deliver: public   base
{
public:
    deliver()
{cout<<"deliver constructor"<<endl;}
    
~deliver(){cout<<"deliver destructed"<<endl;}
}
;

int  main()
{
    deliver d;

    
return 0;
}

base constructor

base destructed

deliver constructor

deliver destructed

生成一个派生类对象时,如果基类有构造函数,则这个构造函数首先被调用,接着调用派生类的构造函数,派生对象删除时,析构函数首先被调用,接着调用基的析构函数.不同的是,构造函数按序,而析构接与派生相反的顺序执行.

 

四.虚基类

防止在MI中,派生类出现含义不清的基类变量.如在下面代码中:

#include  < iostream >

using   namespace  std;

class   base
{
public:
    
int i;
}
;

class  deliver1: public   base
{
public :
    
int j;
}
;

class  deliver2: public   base
{
public:
    
int k;
}
;

class  deliver3: public  deliver1, public  deliver2
{
    
int sum;
}
;

int  main()
{
    deliver3 d3;
    d3.i
=10;
    d3.j
=10;
    d3.k
=30;
    d3.sum
=d3.i+d3.j+d3.k;


    
return 0;
}

程序会报错,因为d3.i=10中,出现的i可能是deliver1的成员也可能是deliver2成员.

稍加修改

#include  < iostream >

using   namespace  std;

class   base
{
public:
     
int i;
}
;

class  deliver1: virtual   public   base
{
public :
    
int j;
}
;

class  deliver2: virtual   public   base
{
public:
    
int k;
}
;

class  deliver3: public  deliver1, public  deliver2
{
public:
    
int sum;
}
;

int  main()
{
    deliver3 d3;
    d3.i
=10;
    d3.j
=10;
    d3.k
=30;
    d3.sum
=d3.i+d3.j+d3.k;


    
return 0;
}

加上virtual后,作为virtual的基类继承保证了在任何派生类中只提供一个基类副本.

如果感兴趣,还可以看看上述两种方式的构造,析构顺序.

 

五.指向派生类的指针

基类指针可以指向派生对象的任何类型,但反过来不成立.

基类指针不能方问那些限制为派生类的元素.它可以访问由基类继承来的派生类元素.

如果想用基类指针来访问由派生类定义的元素,那么就必须把基类指针强制转化为派生类的指针,如:((deliver_class*)p)->show_title();

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值