您的位置:首页 > 编程语言 > C语言/C++

面试题:C++实现一个不能被继承的类

2017-07-15 20:51 489 查看
一个子类继承一个父类,子类的构造函数和析构函数会自动调用父类的构造函数,

先要求设计不能继承的类,即不允许子类的构造函数调用父类的构造函数和析构函数,方法如下:

1.直接的方法:将父类的构造函数和析构函数设置为private成员函数

私有成员只能被自身的类访问

class  A
{
public:
static A* Create()
{
return new A();
}

static void Delete(A* p)
{
delete p;
}

private:
A(){}
~A(){}
};

class B:public A
{
public:
B(){}
~B(){}
};
int main()
{
//B b;
//A a;
A* p = A::Create();
A::Delete(p);
getchar();
return 0;
}


例中类B 就不能访问类A,因为A的构造函数和析构函数定义为private成员,但是此时类A定义A类实例时会发生错误,怎样才能的到该类型的实例呢?我们可以通过公有的静态函数和创建和释放该类的实例,即上述的 static A* Create()和static void Delete(A* p)函数。

该方法的缺点:

该类的实例只能在堆上创建

与我们常见的类的构造与析构不同

2.利用虚继承

首先,我们先来复习一下虚继承

在我们学习菱形继承的时候,我们知道在一个类中保留间接共同基类的多份同名成员,这种现象造成的问题是保留多份数据成员的拷贝,浪费空间,且访问该成员是容易出错;为了解决该问题,我们提出了虚继承的学习。

虚继承,使得在继承间接共同基类时只保留一份成员

规定:C++编译系统只执行最后的派生类对基类的构造函数的调用,而忽略基类的其他派生类对虚基类的构造函数的调用

template<class T>
class makeSealed
{
public:
friend T;
private:
makeSealed(){}
~makeSealed(){}
};

class SealedClass:virtual public makeSealed<SealedClass>
{
public:
SealedClass(){}
~SealedClass(){}
};

class A :public SealedClass
{
public:
A(){}
~A(){}
};

int main()
{
A a;
SealedClass s;
getchar();
return 0;
}


类SealedClass虚继承类makeSealed,此时将makeSealed类的构造函数和析构函数设置为私有成员函数,而Sealed为makeSealed类的友元函数,可以访问该类;

此时,若我们定义一个类A继承SealedClass类,类A将会跳过SealedClass类的构造函数直接去访问类makeSealed的构造函数,但类makeSealed的构造函数是私有成员,不能访问,故SealedClass不能被继承。

该方法的优点:

类的实例既可以在堆上创建,又可以在栈上创建;

更符合类的表示
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  不能被继承的类