C++ 炫技写法——不能被继承的类

不能被继承的类

在 C++ 11 中,我们引入了一个强大的武器——final 关键字,用于让类无法被继承。不过,假如你想在不使用 final 的情况下实现同样的效果,那该怎么办呢?让我们来看看如何利用友元函数和虚继承来实现这一目标,尽管这条路并不总是那么平坦!

友元函数 + 虚继承的实现

首先,得承认使用友元函数有点儿“破坏封装”的意思。在编码的世界里,封装就像是一堵保护墙,但友元函数却能轻易地把这堵墙拆掉。同时,虚继承的性能损耗也让人心头一紧。因此,除非迫不得已,建议还是用 final 关键字来简单明了地解决问题。

示例代码

接下来,我们看下如何实现一个“不能被继承”的类。

#include <iostream>

class A {
private:
    // 私有构造函数,只有友元可以访问
    A() {}
    friend class B; // B 是 A 的友元类
};

// 这里 B 继承 A,但没有使用 virtual
class B : public A {
public:
    int m_b;
};

// C 试图继承 B
class C : public B {
public:
    int m_c;
};

int main() {
    B myobjb; // B对象可以正常创建
    myobjb.m_b = 15;
    
	// class B : public A ,没有使用 virtual 可以正常创建
    C myobjc; 
    myobjc.m_c = 22;	

	// class B : virtual public A ,使用 virtual 编译错误
    // C myobjc;  // 将会失败

    return 0;
}

在上面的代码中,B 类是 A 类的友元类,因此它能够使用 A 的私有构造函数,这样 B 对象可以顺利创建。可惜的是,B 目前仍然可以被 C 继承,这显然不符合我们的设想。

实现“不能被继承”

为了让 B 类不能被继承,我们可以虚继承 A 类,代码如下:

class B : virtual public A {
public:
    int m_b;
};

这样做后,B 类的对象可以被正常构造,但如果我们尝试创建 C 类的对象,就会遇到编译问题。可以说,这个 B 类就如同一个高墙,进不去的也正是我们想要的效果!

编译结果

如果编译上述代码,试图实例化 C 类时,你将会看到如下错误:

error: call to implicitly-deleted default constructor of 'C'
error: use of deleted function 'C::C()'
error: 'A::A()' is private within this context

这说明 C 类无法构造,因为 A 的构造函数是私有的,而这个正是我们想要的效果——阻止 B 类被继承。

结尾总结

通过巧妙地利用虚继承和友元关系,我们成功实现了一个类不能被继承的目标。尽管这种方法在理论上是可行的,但它也伴随着一些问题,比如破坏封装性和可能带来的性能开销。在实际开发中,除非有特殊需求,还是推荐大家使用 final 关键字,因为它简单有效,更符合我们开发的初衷。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值