怎么防止类被继承?对于不能被继承的类,怎么初始化及销毁它的实例?
2011-10-05 15:14
357 查看
“怎么防止类被继承?对于不能被继承的类,怎么初始化及销毁它的实例?”这是ADOBE公司的一道笔试题。
看了这道题目,笔者查阅了一些资料并结合自己的一些想法,写了这篇博客,有错误的地方请指出,谢谢。
首先看怎么防止类被继承。这里面介绍一种借用虚继承和友元机制实现的方法。其实说到底,防止一个类被继承,我们还是想怎么使的派生类在构造时不能够调用基类的构造函数,从而不能完成继承。我们都知道,派生类对象初始化时,首先要运行基类构造函数,将基类子对象进行初始化,之后再运行派生类的构造函数,初始化派生类中特质不同的成员。下面介绍一种方法:
#include <iostream>
using namespace std;
class Base1;
class Base{
public:
~Base(){cout<<"Base::~Base()"<<endl;}
friend class Base1;
private:
Base(){cout<<"Base::Base()"<<endl;}
};
class Base1: virtual public Base{ //虚继承
public:
Base1(){cout<<"Base1::Base1()"<<endl;}
~Base1(){cout<<"Base1::~Base1()"<<endl;}
};
class Drived: public Base1{
public:
Drived(){cout<<"Drived::Drived()"<<endl;}
~Drived(){cout<<"Drived::~Drived()"<<endl;}
};
int main(){
Drived D;
}
首先定义一个基类Base,但在Base类中,其构造函数被定义为私有的。接下来Base1虚继承Base类,Base类成了虚基类,而Base1是Base的友元,可以调用Base的构造函数初始化对象。但是到了派生类Drived时候,它是最低层的派生类,按照规则“最低层派生类的构造函数初始化虚基类”,Drived类跨过Base1直接调用Base类中的构造函数去初始化虚基类部分的子对象,然而由于Base类的构造函数是私有的,Drived类的构造函数无权调用,因此初始化失败。这就导致了一个有趣的现象,Drived类继承Base1类,结果由于无法调用虚基类Base的构造函数而无法完成对象的创建,给人的感觉就是Base1类无法被继承。
再来看看问题的后半部分“对于不能被继承的类,怎么初始化及销毁它的实例?”这里不能被继承的类是Base1类,但是Base1类如果创建对象的话,可以正常的调用Base类和Base1类的构造函数和析构函数完成初始化和销毁操作。这也说明了,虚继承具有这样的特点:类A虚继承类B,类A的操作一切都正常,造成影响的是A的派生类C。因为虚基类A的派生类C要在构造非虚基类B之前去构造虚基类A。
看了这道题目,笔者查阅了一些资料并结合自己的一些想法,写了这篇博客,有错误的地方请指出,谢谢。
首先看怎么防止类被继承。这里面介绍一种借用虚继承和友元机制实现的方法。其实说到底,防止一个类被继承,我们还是想怎么使的派生类在构造时不能够调用基类的构造函数,从而不能完成继承。我们都知道,派生类对象初始化时,首先要运行基类构造函数,将基类子对象进行初始化,之后再运行派生类的构造函数,初始化派生类中特质不同的成员。下面介绍一种方法:
#include <iostream>
using namespace std;
class Base1;
class Base{
public:
~Base(){cout<<"Base::~Base()"<<endl;}
friend class Base1;
private:
Base(){cout<<"Base::Base()"<<endl;}
};
class Base1: virtual public Base{ //虚继承
public:
Base1(){cout<<"Base1::Base1()"<<endl;}
~Base1(){cout<<"Base1::~Base1()"<<endl;}
};
class Drived: public Base1{
public:
Drived(){cout<<"Drived::Drived()"<<endl;}
~Drived(){cout<<"Drived::~Drived()"<<endl;}
};
int main(){
Drived D;
}
首先定义一个基类Base,但在Base类中,其构造函数被定义为私有的。接下来Base1虚继承Base类,Base类成了虚基类,而Base1是Base的友元,可以调用Base的构造函数初始化对象。但是到了派生类Drived时候,它是最低层的派生类,按照规则“最低层派生类的构造函数初始化虚基类”,Drived类跨过Base1直接调用Base类中的构造函数去初始化虚基类部分的子对象,然而由于Base类的构造函数是私有的,Drived类的构造函数无权调用,因此初始化失败。这就导致了一个有趣的现象,Drived类继承Base1类,结果由于无法调用虚基类Base的构造函数而无法完成对象的创建,给人的感觉就是Base1类无法被继承。
再来看看问题的后半部分“对于不能被继承的类,怎么初始化及销毁它的实例?”这里不能被继承的类是Base1类,但是Base1类如果创建对象的话,可以正常的调用Base类和Base1类的构造函数和析构函数完成初始化和销毁操作。这也说明了,虚继承具有这样的特点:类A虚继承类B,类A的操作一切都正常,造成影响的是A的派生类C。因为虚基类A的派生类C要在构造非虚基类B之前去构造虚基类A。
相关文章推荐
- 怎么防止类被继承?对于不能被继承的类,怎么初始化及销毁它的实例?
- 怎么防止类被继承?对于不能被继承的类,怎么初始化及销毁它的实例?
- 怎么防止类被继承?对于不能被继承的类,怎么初始化及销毁它的实例?
- 数据结构之栈的初始化、创建、入栈、出栈、销毁-c++代码实现及运行实例结果
- python类继承与子类实例初始化用法
- 【Vegas原创】C#不能多重继承,怎么办?接口!
- 数据结构之栈的初始化、创建、入栈、出栈、销毁-c++代码实现及运行实例结果
- C++实现不能被继承的类实例分析
- C++设计类不能被继承的方法实例讲解
- 【转】C++怎么设计只能在堆或者栈分配空间的类以及定义一个不能被继承的类
- 怎么使用继承的一个实例
- 数据结构之栈的初始化、创建、入栈、出栈、销毁-c++代码实现及运行实例结果
- 注册或者点击按钮时,怎么防止用户重复提交数据(实例讲解)
- 数据结构之栈的初始化、创建、入栈、出栈、销毁-c++代码实现及运行实例结果
- 2--spring bean 的作用域scope 设置;bean的初始化和销毁方法,profile配置不同环境实例化不同的bean,自定义事件,自定义监听器
- 当您更改为一个值该值不是有效的启动参数对于群集实例的 SQL Server 2000 或 SQL Server 2005 的 SQL Server 服务不能启动
- JAVA final 、super 关键字以及继承关系中父类与子类实例变量初始化的 理解
- python 类继承与子类实例初始化
- viewpager防止fragment销毁和以及取消fragment的预加载(平常开发时不怎么考虑这个问题)
- 数据结构之栈的初始化、创建、入栈、出栈、销毁-c++代码实现及运行实例结果