private

private:
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类时就会报错,这是为什么呢?

因为:

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。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值