Effective C++: 关于继承中的函数的访问级别的修改.

我们来分两种情况:

1,如果当前基类中的函数是一个虚函数(virtual-function)无论它在基类中是什么样的访问级别(private,protected,public)我们都能通过在派生类中修改对该虚函数重写(override)的时候通过把它声明到到不同的访问级别(private public, protected)下来修改该虚函数在派生类中的可访问级别.

2,如果当前基类中的函数是一个普通函数,如果他在基类中是private的,我们就没法通过using修改它在派生类中的可访问级别,如果他是public,protected的是可以通过using来修改的. 另外还需要特别注意的是如果是构造函数我们是没办法通过using来修改基类中的构造函数的访问级别的.

 

3,无论是private继承还是protected继承都是不能使用多态的.


#include <iostream>


class Base{
 private:
  int private_number;
  
  void private_print()const;
  
  virtual void virtual_private()const; 
  
  protected:
   int protected_number;
   
   void protected_print()const;
   
   virtual void virtual_protected()const;
   
   public:
    Base()=default;
    
    Base(const int& first_, const int& second_);
    
    virtual ~Base()=default;
};

​

Base::Base(const int& first_, const int& second_)
     :private_number(first_),
      protected_number(second_)
{
 //
}

​

void Base::virtual_protected()const
{
 std::cout<<this->protected_number<<" :virtual_protected"<<std::endl;
}
​

​​

void Base::protected_print()const
{
 std::cout<<this->protected_number<<" :protected_print"<<std::endl;
}

​

void Base::private_print()const
{
 std::cout<<this->private_number<<" :private_print"<<std::endl;
}

​

void Base::virtual_private()const
{
 std::cout<<this->private_number<<" :virtual_private"<<std::endl;
}

​
​
//private继承: 
class BigNode : private Base {
 private:
  std::string str_;
  
  //virtual void virtual_private()const override;  //如果该虚函数被声明在这里那么他的访问级别就是private的. 
  
  public:
   //using Base::private_print; //error, 这里我们试图通过using把private级的private_print改成public的.
                              //这样是没有任何卵用的因为我们是无权更改基类中的private数据的,无论派生类是以怎么样的形式继承的基类. 
   
   BigNode(const int& first_, const int& second_, const std::string& s);
   
   ~BigNode()=default;
   
   void print()const;
   
   virtual void virtual_private()const override;
   
   virtual void virtual_protected()const override;  //注意这里: 从Base中以private的形式继承过来的,
                                           //但是这里被我们override在了public区域内因此该虚函数的访问级别也就变成了public的了. 
   
   protected:
    using Base::protected_print; //注意这里我们通过using Base::protected_print把继承后本该属于private级别的protected_print函数改成了protected级别. 
};


​

BigNode::BigNode(const int& first_, const int& second_,const std::string& s)
        :Base(first_, second_),
         str_(s)
{
 //
}

​

void BigNode::print()const
{
 //this->private_print(); //error.因为该函数在Base中是private级的. 
                          //继承过来仍然是private级别的.
         
 this->protected_print();
}

​​

void BigNode::virtual_private()const
{
 std::cout<<"BigNode-virtual-private: "<<this->str_<<std::endl;
}
​

​

void BigNode::virtual_protected()const
{
 std::cout<<"BigNode-virtual-protected: "<<this->str_<<std::endl;
}
​
​
//protected继承: 
class SmallNode : protected Base{
 private:
  char c_;
  
  public:
   using Base::protected_print; //修改了protected_print的访问级别.现在是public的. 
   
   //using Base::private_print; //error.
   
   SmallNode(const int& first_, const int& second_, const char& c);
   
   ~SmallNode()=default;
   
   void print()const;
   
   protected:
    
    virtual void virtual_private()const override;
    
    virtual void virtual_protected()const override;
};

​

SmallNode::SmallNode(const int& first_, const int& second_, const char& c)
          :Base(first_, second_),
           c_(c)
{
 //
}

​​

void SmallNode::print()const
{
 //this->private_print();
 this->virtual_private();
 this->virtual_protected();
}
​
​

void SmallNode::virtual_private()const
{
 std::cout<<"SmallNode-virtual-private: "<<this->c_<<std::endl;
}
​
​

void SmallNode::virtual_protected()const
{
 std::cout<<"Small-virtual-protected: "<<this->c_<<std::endl;
}
​
int main()
{
 BigNode node(5, 20, "shihuawoaini");
 node.print();
 //node.protected_print(); //注意BigNode是以private的级别继承的Base,因此该protected_print函数在BigNode中默认应该是private的. 
                          //我们通过using Base::protected_print更改了该函数的级别. 该函数被设置为了proteced级别的. 
                         //如果我们想在这里调用该函数可以在public级别下通过using Base::protected_print修改该函数的级别为public. 
                         
 //Base* ptr = &node; //error.因为BigNode是以private的形式继承的Base所以不能使用多态. 
 
 node.virtual_private();    //ok. 因为我们把该虚函数声明到了public区域内. 
 node.virtual_protected(); //ok. 
 
 SmallNode node_two(2, 5, 's');
 node_two.print();
 node_two.protected_print();
 
 //Base* ptr_small = &node_two; //error.因为SmallNode是以protected的形式继承的Base所以不能使用多态. 
 
 
 return 0;
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/648259

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值