精华内容
下载资源
问答
  • private继承截断了继承的访问通道,下一个孙子派生类将无法访问爷爷基类的public和protected成员,同时关闭了派生类对象直接访问基类public成员的通道。 protected继承则依旧保持了继承访问通道的畅通,但同时也关闭...

    题外话,关于基类的protected成员(虽然是题外话,但是这个点对于讲继承很重要)

    在总结这三种继承方式之前,要先澄清两个误区。

    一、类的访问权限修饰,是类级别的,也就是class level的,而不是对象级别的。同一个类的两个不同的对象,是可以互相访问对方的保护成员和私有成员的。

    二、好多人对下面这句话都曾经有过一个错误的认识。

    “对于基类的protected成员,派生类的成员函数和友元函数具有访问权限。”(这是一句不应该说的话,因为表达出来的意思很容易让人产生误解)

    这句话说的比较模糊,完整清楚的表达应该是:“派生类的成员函数和友元函数,可以访问派生类对象中的基类部分的protected成员(和public成员)。但是,对于独立的基类对象中的protected成员,派生类是没有访问权限的,除非又把派生类声明为基类的友元类。” 
    为了理解上面这一段话,请考虑下面这个例子。

    class Base{
    public:
    	void pub_mem();
    protected:
    	int prot_mem;
    private:
    	char priv_mem;
    };
    
    class Derived : public Base{
    public:
    	int visitBaseObj(Base&);
    	int visitBaseObj_1();
    }
    
    int Derived::visitBaseObj(Base& Bobj){
    	return ( Bobj.prot_mem );		//错误,不能通过基类对象直接访问Base的protected成员
    }
    int Derived::visitBaseObj_1(){
    	return prot_mem;			//正确,派生类的成员函数和友元函数,可以访问派生类的基类部分的protected成员
    }

    题外话说完,回到正题。


    C++的继承有三种方式,public继承、protected继承和private继承。
    提到继承,就肯定会提到基类和派生类,注意,我们这里说的基类都是默认指的直接基类,如果用到间接基类,会显式强调指出的。

    1. 这三种继承不论是哪种继承,基类的private在派生类的基类部分,还是基类部分的private,这个private对子类都是拒绝访问的。
    2. 对于public继承:就是把基类的public变成了派生类中带有基类域属性的public,把基类的protected变成了派生类中带有基类域属性的protected;
    3. 对于protected继承:就是把基类的public和protected变成了派生类中带有基类域属性的protected,注意这个protect的所有权是属于派生类的;
    4. 对于private继承:就是把基类的public和protected变成了派生类中带有基类域属性的private,注意这个private的所有权是属于派生类的。
    5. 类的对象只能访问本类中的public成员,类中的成员函数和友元可以访问类中(除了基类部分的private成员)的所有成员。
    简单可依赖。


    下面展开来细讲一下。

    总的来说,某个类对其继承而来的成员的访问权限受到两个因素的影响:一是在基类中该成员的访问说明符;二是在派生类的派生列表中的访问说明符。
    值得注意的是,对于派生类中的成员函数和友元函数能否访问  派生类的基类部分的成员,派生列表中的访问说明符  是不会产生什么影响的。

    派生类中的成员函数和友元函数,对派生类的基类部分的成员的访问权限,只与基类中的访问说明符有关。举个例子:

    class Base{
    public:
    	void pub_mem();
    protected:
    	int prot_mem;
    private:
    	char priv_mem;
    };
    
    struct Pub_Derv : public Base{
    	//f()函数正确,派生类可以访问 派生类的基类部分 的protected成员
    	int f() {	return prot_mem;	}
    	//g()函数错误,派生类不可以访问 派生类的基类部分 的private成员
    	char g() {	return priv_mem;	}
    };
    //对于派生类的成员函数和友元函数 的访问权限,private和protected继承对其不产生任何影响(但是一会儿要讲,会影响派生类对象的访问权限)
    struct Priv_Derv : private Base{
    	//f()函数正确,派生类可以访问 派生类的基类部分 的protected成员
    	int f() {	return prot_mem;	}
    	//g()函数错误,派生类不可以访问 派生类的基类部分 的private成员
    	char g() {	return priv_mem;	}
    };

    看到这里,我们知道了 派生列表中的访问说明符,对于 派生类中的成员函数和友元函数能否访问  派生类的基类部分的成员,不会产生任何影响。


    那么派生列表中的访问说明符,有什么作用呢?有两点作用。

    • 第一点作用:派生访问说明符,是用于控制派生类用户(包括派生类的派生类在内),对于派生类的基类部分的成员的访问权限。  派生类用户,说白了就是指由派生类生成的对象。类的对象只能调用本类中的public成员。

    接着上面的例子,

    Pub_Derv pub_obj;
    Priv_Derv priv_obj;
    
    pub_obj.pub_mem();		//正确,派生类对象可以访问派生类的基类部分的public成员
    pub_obj.prot_mem;		//错误,对象只可以访问本类的public成员
    
    priv_obj.pub_mem();		//错误,派生类对象不可以访问派生类的基类部分的原先的public成员,因为此时pub_mem()在派生类中是private的

    • 第二点作用:派生类访问说明符还可以控制继承自派生类的新类的访问权限。
    对于private继承,则在Priv_Derv类中,继承自Base的所有成员都是私有的,但这个私有是有区别的。Base基类以前的private现在仍是派生类中基类部分自己私有的,但是Base基类以前的public和protected现在是派生类私有的,是可以被派生类的成员函数和友元所访问的。

    如果是protected继承,则在Prot_Derv类中,继承自Base的所有public和protected成员都是protected的,而Base中原有的private成员仍是派生类的基类部分自己private的。

    所以可以看到:

    • private继承截断了继承的访问通道,下一个孙子派生类将无法访问爷爷基类的public和protected成员,同时关闭了派生类对象直接访问基类public成员的通道。
    • protected继承则依旧保持了继承访问通道的畅通,但同时也关闭了派生类对象直接访问基类public成员的通道。

    私有继承和保护继承,建立的是has-a关系。所以这两种继承又被称为继承实现,但不继承接口。因为派生类对象不能显式地使用基类的接口。因此,不能将派生类对象看做是一种基类对象。也正是 由于这个原因,在不进行显式转换的情况下,基类指针或引用将不能指向派生类对象


    展开全文
  • 1、private继承意味着,根据某物实现出,继承父类的实现,关闭父类的接口,并不是Is-A的关系,不满足里氏代换,继承的内容访问权限都修改为private。 2、那么问题来了,复合也表达根据某物实现出,那到底使用...

    1、private继承意味着,根据某物实现出,继承父类的实现,关闭父类的接口,并不是Is-A的关系,不满足里氏代换,继承的内容访问权限都修改为private。

    2、那么问题来了,复合也表达根据某物实现出,那到底使用private继承还是复合呢?

    3、优先使用复合,除非是下面的情况:a、使用对象的protected成员;b、想要重新定义virtual方法。

    4、考虑下面的极端情况,有个empty类,占用空间大小为0,也就是说,没有字段和virtual方法,如果使用继承,子类大小不增加。如果使用复合,C++规定大小为0的独立对象,插入一个char到空对象,考虑到对齐,实际占用int。也就是说,在这种极端的情况下,继承比复合节省空间。对于空间格外重要的使用场景,需要考虑这种情况。

    转载于:https://www.cnblogs.com/nzbbody/p/3528768.html

    展开全文
  • 14.8空对象(一)

    2018-06-06 00:56:05
    依然可以响应对象的所有信息,你仍需要某种方式去测试其是否为空解决方案:public interface Null {}这样可以使用instanceof 探测空对象,省去isNull()方法 *使用默认权限使用包外无法使用,关闭包外继承 * */ ...

    尽可能的避免空指针异常:

        想要达到:即使对象是空值,依然可以响应对象的所有信息,你仍需要某种方式去测试其是否为空

    解决方案:

    public interface Null {}

    这样可以使用instanceof 探测空对象,省去isNull()方法

     *使用默认权限使用包外无法使用,关闭包外继承
     *
     */
     class Person {
    	//从技术的角度来说,不可变类是允许公有域的,虽然这样不太好
    	public final String first;
    	public final String last;
    	public final String address;
    	
    	//实例化必需赋值
    	public Person(String first, String last, String address) {
    		super();
    		this.first = first;
    		this.last = last;
    		this.address = address;
    	}
    	
    	
    	@Override
    	public String toString() {
    		return "Person [first=" + first + ", last=" + last + ", address=" + address + "]";
    	}
    	
    	//嵌套类 使用static 修饰关闭与外围类的关联,相对独立存在 
    	public static class NullPerson extends Person implements Null{
    		
    		private NullPerson() {
    			super("None","None","None");
    		}
    		
    		public String toString() {
    			return "NullPerson";
    		}
    		
    	}
    	
    	//单例模式
    	public static final Person NULL = new NullPerson();
    }

    通常,空对象都是单例,注意,此对象为不可变对象,这个对象里面的值是没胡办法修改的,它的空值是可以用instanceof 来探测的 ,

    为什么使用单例:

    可以使用equals()甚至==来与Person.NULL来进行比较

    public class Position {
    	private String title;
    	private Person person;
    	public Position(String jobTitle, Person employee) {
    		super();
    		title = jobTitle;
    		person = employee;
    		if(person == null) 
    			person = Person.NULL;
    	}
    	
    	public Position(String jobTitle) {
    		super();
    		title = jobTitle;
    		person = Person.NULL;
    	}
    
    	public String getTitle() {
    		return title;
    	}
    
    	public void setTitle(String title) {
    		this.title = title;
    	}
    
    	public Person getPerson() {
    		return person;
    	}
    
    	public void setPerson(Person person) {
    		if(person == null) 
    			person = Person.NULL;
    	}
    
    	@Override
    	public String toString() {
    		return "Position [title=" + title + ", person=" + person + "]";
    	}
    	
    }

    如何代表空职位:

    就是Person.NULL,需要Position的空对象,但是你不需要申明它 PS:极限编程的原则之一:做可以工作的最简单的事情

    public class Staff extends ArrayList<Position>{
    	public void add(String title,Person person) {
    		add(new Position(title, person));
    	}
    	
    	public void add(String... titles) {
    		for(String title:titles) {
    			add(new Position(title));
    		}
    	}
    
    	public Staff(String... titles) {
    		add(titles);
    	}
    	
    	public boolean positionAvailable(String title) {
    		for(Position position:this) {
    			if(position.getTitle().equals(title) && position.getPerson() == Person.NULL)
    				return true;
    		}
    		return false;
    	}
    	
    	public void fillPosition(String title,Person person) {
    		forEach(position->{
    			if(position.getTitle().equals(title) && position.getPerson() == Person.NULL)
    				position.setPerson(person);
    			return;
    		});
    	}
    	
    }

    或许到这里,你依然需要测试空对象,这与检查null没胡差异,但是在其它地地方,你就不必执行额外的测试,可以直接假设所的对象都是有效的

    展开全文
  • 2、打开文件夹属性-安全-高级-权限,选择“更改权限”,勾选“包括可从该对象的父项继承权限”,确定后小锁图标消失。 3、添加所有用户权限:右击文件夹图标-共享-特定用户,在弹出窗口中点击下拉菜单中选择...

    三种方式去除小锁图标:

    1、添加共享文件夹用户组:打开文件夹属性-安全,添加“Authenticated Users”用户组。

    2、打开文件夹属性-安全-高级-权限,选择“更改权限”,勾选“包括可从该对象的父项继承的权限”,确定后小锁图标消失。

    3、添加所有用户权限:右击文件夹图标-共享-特定用户,在弹出窗口中点击下拉菜单中选择“Everyone”,再依次点击“添加”-“共享”-“完成”,这样设置的共享文件夹上就没有锁的标记,取消共享时,只要右击文件夹选择“属性”,再选择“共享”中的“高级共享”,取消其中“共享文件夹”前的勾,确定退出后就不会有小锁的图标了,如果不按这种方法取消共享,小锁标志会重新出现在文件夹图标上。

    展开全文
  • 3、上一步点击确定之后,出现弹框,勾选图中的替换子容器和对象的所有者,点击应用 4、上一步点击确定之后,关闭所有弹窗,重新点击文件夹属性-》安全-》高级,出现弹框,点击添加,再出现弹框,点击选择主体如图,...
  • 面向对象都有哪些特性以及你对这些特性的理解 ... 继承:对扩展开放,对修改关闭的原则的体现,子类继承父类,子类可以获得除private权限以外的所有父类属性,子类可以拥有自己方法,或者重写父...
  • 封装、抽象、继承、多态分别可以解决哪些编程问题 封装: 特性: 控制访问权限 意义: 暴露有限的接口,达到业务隔离,只提供必要的操作,隐藏信息,保护数据,提高类的易用性。...面向对象编程(面向对象编程语
  •  5.2.1 public权限修饰  5.2.2 关于构造函数  5.2.3 构造函数与方法重载  5.2.4 使用this  5.2.5 static类成员  5.2.6 不定长度自变量  5.2.7 内部类  5.2.8 传值调用  5.3 重点复习  5.4 课后...
  • 设计模式小结

    2016-08-29 13:58:00
    首先是面向对象的几个原则: 1.开闭原则OCP(对扩展开放,对修改关闭) 2.里氏代换原则LSP(子类重写方法访问权限不能小于父类) ps:关于重写(override)和重载(overload) 重载是在同一个类中定义几种方法名相同,...
  • 4.2.4.NTFS权限继承 4.3.NTFS权限设置 4.3.1 设置NTFS权限基本策略和原则 4.3.2 取消“Everyone”完全控制权限 4.4 特殊访问权限 4.4.1 指定特殊访问权限 4.4.2 复制和移动文件夹对权限的影响 4.5 文件审核设置 ...
  • 其相当于everyone 但范围扩展到所有安全对象(如:计算机),该用户具有采用组策略的权限,a、b都是其成员。删除 再次以用户 a 登录到客户机 网上邻居出现(OU组策略被过滤,与预期相同) 以非ab 组中用户 c 登录到...
  • Spring面试题

    2015-05-06 07:19:39
    4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入...
  • Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过Servelet容器)等功能 spring-expression:提供了强大的表达式语言,用于在运行时查询和...
  • 5.2.1 public权限修饰 134 5.2.2 关于构造函数 136 5.2.3 构造函数与方法重载 137 5.2.4 使用this 139 5.2.5 static类成员 142 5.2.6 不定长度自变量 148 5.2.7 内部类 150 5.2.8 传值调用 151 5.3...
  • 3.3.1 使用对象句柄继承 3.3.2 改变句柄的标志 3.3.3 为对象命名 3.3.4 终端服务命名空间 3.3.5 专有命名空间 3.3.5 复制对象句柄 第Ⅱ部分 工作机制 第4章 进程 4.1 编写第一个Windows应用程序 4.1.1 进程实例句柄 ...
  • Java2核心技术第7版全两卷.pdf中文高清

    千次下载 热门讨论 2012-09-14 14:22:28
    3.5.3 半关闭 158 3.5.4 因特网地址 158 第4章 数据库编程 162 4.1 jdbc的设计 162 4.1.1 jdbc驱动程序类型 163 4.1.2 jdbc的典型用法 164 4.2 结构化查询语言 165 4.3 安装jdbc 168 4.4 jdbc编程的基本概念...
  • 对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以...
  • 6.角色管理,每一个角色都能配置相应的权限,如果用户组的子组可以继承父组的权限; 7.系统管理员管理; 8.用户操作日志列表,只能删除三个月以前的; 9.站点自动导航页面,可增加一些常用的内容页; 10.相关缓存的...
  • 10.10 对象到linq对象的映射 429 10.10.1 datacontext对象 430 10.10.2 table(tentity)对象 432 10.11 查询数据库 433 10.11.1 使用查询表达式 433 10.11.2 查询表达式详述 433 10.11.3 用表达式过滤 434 ...
  • java 面试题 总结

    2009-09-16 08:45:34
    对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以...
  • 10.10 对象到linq对象的映射 429 10.10.1 datacontext对象 430 10.10.2 table(tentity)对象 432 10.11 查询数据库 433 10.11.1 使用查询表达式 433 10.11.2 查询表达式详述 433 10.11.3 用表达式...
  • 10.10 对象到linq对象的映射 429 10.10.1 datacontext对象 430 10.10.2 table(tentity)对象 432 10.11 查询数据库 433 10.11.1 使用查询表达式 433 10.11.2 查询表达式详述 433 10.11.3 用表达式过滤 ...
  • 10.10 对象到linq对象的映射 429 10.10.1 datacontext对象 430 10.10.2 table(tentity)对象 432 10.11 查询数据库 433 10.11.1 使用查询表达式 433 10.11.2 查询表达式详述 433 10.11.3 用表达式过滤 434 ...
  • 10.10 对象到linq对象的映射 429 10.10.1 datacontext对象 430 10.10.2 table(tentity)对象 432 10.11 查询数据库 433 10.11.1 使用查询表达式 433 10.11.2 查询表达式详述 433 10.11.3 用表达式过滤 434 ...
  • win7简明封装教程

    2010-03-16 12:52:12
    再点权限-编辑-添加,把你的用户名填入或者用高级-立即查找,确定,再点击你的用户名-编辑,把完全控制/允许那个打勾,确定,再把使用可从此对象继承的权限替换所有后代上现有的可继承权限打勾,同前面,这个不...
  • 14.4.6响应窗口关闭事件处理示例454 14.4.7事件监听器接口和适配器类456 14.4.8作为参数的事件类456 14.4.9处理多个事件的例子463 14.5Swing组件的特性467 14.5.1Swing组件的优势467 14.5.2Swing组件的体系...
  • 13.4.3 面向对象封装、继承、多态的应用 468 13.4.4 设计模式、条件外置及反射技术的应用 471 13.5 面向对象分析(OOA)的方法 475 13.6 面向对象设计的原则 478 13.6.1 优先使用(对象)组合,而非(类)继承 478 ...

空空如也

空空如也

1 2 3 4 5 6
收藏数 111
精华内容 44
关键字:

关闭对象继承权限