我们来分两种情况:
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;
}