When preceding a list of class members, the private keyword specifies that those members are accessible only from member functions and friends of the class. This applies to all members declared up to the next access specifier or the end of the class.
When preceding the name of a base class, the private keyword specifies that the public and protected members of the base class are private members of the derived class.
以上转自MSDN,但是C++ Primer里说到:
In private inheritance , all the members of the base class are private in the derived class.
两中说法有不同之处。由下例的说明3可知:
第一种说法正确,即基类的protected和public成员通过private继承成为了派生类的private成员。
第二种说法不准确,基类的private成员可以被派生类private继承,但该成员(如下例的width)不可以被派生类自己定义的成员函数(如下例的public_display)访问,奇怪的是该成员可以被同样是继承自基类的成员函数(如下例的set_width和display_width)访问。
class cube
{
public:
cube(int i = 0, int j = 0, int k = 0):length(i), width(j), height(k) {} //1!!!
int length;
void display_length() { cout << "length:" << length << endl; }
void set_length(int i) { length = i; }
void display_width() { cout << "width:" << width << endl; }
void set_width(int i) { width = i; }
void display_height() { cout << "height:" << height << endl; }
void set_height(int i) { height = i; }
private:
int width;
protected:
int height;
};
class private_cube: private cube
{
public:
void public_display()
{
length++;
display_length();
height++;
display_height();
set_width(3);
display_width();
}
};
int main()
{
cube c1;
private_cube private_c2;
c1.display_width();
//pc2.display_length(); //2!!! error
private_c2.public_display(); //3!!!
c1.display_width();
return 0;
}
输出:
width:0
length:1
height:1
width:3
width:0
说明:
1、需要在cube的constructor中给各成员赋默认值。因为是private继承,cube类的constructor被继承为private_cube类的私有构造函数,如果不加默认值的话,在定义private_cube类时就会报错,这是为什么呢?
因为:
A default constructor is a constructor that either has no parameters, or if it has parameters, all the parameters have default values.
If no user-defined constructor exists for a class A and one is needed, the compiler implicitly declares a default parameterless constructor A::A().
When a derived class constructor does not explicitly call the base class constructor in its initializer list, the default constructor for the base class is called
有默认值的话,cube类的构造函数就是默认构造函数;没有默认值,cube类就没有默认构造函数。
因为cube类定义了构造函数,所以用cube初始化对象时不会合成默认构造函数。而当初始化private_cube对象时,会调用cube的默认构造函数进行初始化,若没有默认值,cube类就没有默认构造函数,所以就报错。
2、因为是私有继承,cube的public和protected成员变量和成员函数都成为private_cube的私有member;而私有member只能通过member function 和friend来访问,不能通过类对象来访问。
3、因为是private继承,private_cube类虽然继承了width,但是应该没有width的访问权限,但是为什么用private_cube的对象调用public_display()接口可以输出width的值呢?查看该链接:http://bbs.csdn.net/topics/390572712?page=1#post-395435359
由输出“width:3”可知,在private_c2.public_display()中调用的set_width(3)将private_cube的成员变量width设置为了3;由最后的输出“width:0”可知,该语句没有改变cube的成员变量width。