码迷,mamicode.com
首页 > 其他好文 > 详细

明智而审慎的使用private继承

时间:2014-11-06 23:19:53      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:blog   io   os   使用   sp   div   on   log   bs   

private继承的意义在于“be implemented in turns of”。

private继承与public继承时完全不同的,主要体现在两个地方

其一,public继承在子类中保持父类的访问权限,即父类中是public的成员函数或者成员便变量可,在子类中仍是public,对private或protected 的成员函数或成员变量亦是如此;但private继承则不是这样的,他破坏了父类红的访问权限标定,将之转成为private,这对子类本省并无影响,但却影响了子类的子类,子类的子类将无法访问这些声明/定义在爷爷辈类的成员变量或成员函数。

其二,Liskov法则不再使用,也就是“一切父类出现的地方都可以被子类替代”的法则在private这里不成立

#include <iostream>

using namespace std;

class  Person{};

class Student:private Person
{};

void eat(const Person& p){}

int main()
{
   Person p;
   Student s;
   eat(p); //ok
   eat(s);  //false
}

  但如果令Student公有继承Person,则编译器不会报错。这正是Liskov的可替代原则在private继承中不适用的体现。

private继承使用的地方实在不多,除非有一些奇葩的设计需求

class TypeDefine
{};

class SimpleClass{
  int a;
  TypeDefine obj;
};

class SimpleDerivedClass:private TypeDefine
{
    int a;
};

int main()
{
   cout<<sizeof(TypeDefine)<<endl;
   cout<<sizeof(SimpleClass)<<endl;
   cout<<sizeof(SimpleDerivedClass)<<endl;
}
 

  第一个类是空类,仅仅是名字的空,看起来是空的,但其实不是这样子的,对于空类,编译器会位子生成默认的函数:默认构造函数,默认拷贝构造函数,,默认析构函数,默认赋值操作符,虽然函数不占空间,但类的每一个对象都须有一个独一无二的内存地址,所以空类的sizeof算出的值是1.非空类因为已经有了成员变量,所以编译器可以利用这些成员变量来进行内存地址的区分,从而表示类的不同对象。

第二个输出的是8,int 4字节再加到空类对象的四字节,理论上编译器还会做一种内存对齐的操作,使得类对象的大小是处理字长的整数倍

第三个输出时4,这其实是编译器做了空白基类优化,原本是要为空白类的对象插入一字节,但因为子类中已经有了对象了,这样理论上就可以凭借这个对象来进行同一个类不同间的识别了,所以这时候编译器就不再插入字节了。

这个结果就是用private继承的好处。

 

明智而审慎的使用private继承

标签:blog   io   os   使用   sp   div   on   log   bs   

原文地址:http://www.cnblogs.com/chillblood/p/4079981.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!