C++中如何定义不能被继承的类

学习过Java和c#的童鞋应该都知道,在Java中定义了关键字final表示一个类不能被继承,在C#中也有相同意义的关键字sealed表示一个类不能被继承,那仫在C++中呢?在C++11之前是没有的类似这样的关键字的,只能自己实现了。(在C++11中该关键字已经被加入到C++中,这个关键字的作用就是阻止类的进一步派生和虚函数的进一步重载)。
如何在C++中定义一个不能被继承的类呢?
想法一:私有构造函数来解决
我们都知道在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。如果想要一个类无法被继承,那仫这个类的构造函数和析构函数必须是私有的,但是这样又会出现新的问题?就是这个类的构造函数和析构函数是私有的,我们如何获取和删除这个类的实例化对象呢?共有的静态函数就可以解决这个问题。

class Base
{
public:
    //编写静态函数来创建和释放类的实例化
    static Base *GetSpace()
    {
        cout<<"GetSpace()"<<endl;
        return new Base();
    }
    static void DeleteSpace(Base *del)
    {
        cout<<"DeleteSpace()"<<endl;
        delete del;
    }
private:
    //私有化构造和析构函数
    Base()
    {}
    ~Base()
    {}
};

int main()
{
    //静态成员函数没有隐含this指针参数,使用类型::作用域访问符直接调用静态成员函数
    Base *b=Base::GetSpace();
    Base::DeleteSpace(b);
    system("pause");
    return 0;
}

私有构造函数和静态成员函数实现不能被继承的类
这样的实现会不会存在什仫问题呢?通过观察上面的代码我发现实例化一个对象只能使用new来实例,也就是说这个新创建的对象只能在堆上生成,这就存在一定的局限性。那仫如何解决呢?
想法二:利用虚拟继承的方法
同样是将父类的构造函数私有化,但是却定义了一个模板类型的友元,因为友元的特性:如果一个类是另一个类的友元,友元类的每个成员函数都是另一个类的友元函数,都可访问另一个类中的保护或私有数据成员。我们在子类中调用父类的构造和析构函数是不会出错的。
这种想法比方法一的想法好的一点就是:既可以在堆上实例化对象也可以在栈上实例化对象。

template<typename T>
class Base
{
    friend T;  //定义友元,子类可以访问父类的私有成员对象
private:
    Base()
    {
        cout<<"Base()"<<endl;
    }
    ~Base()
    {
        cout<<"~Base()"<<endl;
    }
};
//虚继承
class Sub:virtual public Base<Sub>  
{
public:
    Sub()
    {
        cout<<"Sub()"<<endl;
    }
    ~Sub()
    {
        cout<<"~Sub()"<<endl;
    }
};

int main()
{
    Sub s1;   //可以在栈上开辟
    Sub *s2=new Sub; //可以在堆上开辟
    delete s2;
    system("pause");
    return 0;
}

虚拟继承
如果此时对Sub进行继承并对继承Sub的类进行实例化的时候是无法编译通过的。因为Sub是虚拟继承,所以当调用Test的构造函数的时候,会跳过Sub而直接调用Base的构造函数,又因为Base的构造函数是私有的且Test并不是Base的友元所以是不能调用的。
所以Sub就是满足题意的不能被继承的类。

class Test:public Sub
{
public:
    Test()
    {
        cout<<"Test()"<<endl;
    }
    ~Test()
    {
        cout<<"~Test()"<<endl;
    }
};

当然了在C++中定义不能被继承的类有许多其他的方法,在这里我就只介绍这两种啦!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值