用C++实现一个不能被继承的类

     题目:用C++设计一个不能被继承的类
     不能被继承?不能被继承?按照继承的理论知识分析,我们只要把类的构造函数设置为私有的,即可解决问题。因为那样的话,子类就没有办法访问基类的构造函数,从而就阻止了进行子类构造对象的任务实现,也就达到了不可继承的目的。

     但是,假设那样,这个类我们怎么使用呢?那这样子给我们的利用也造成了一定的障碍。好了。你是不是也想到了,定义静态方法,在方法内部实现一个对象,然后返回它的指针。Ok?那怎么释放掉呢?再照样设计一个释放内存函数,问题就会迎刃而解。OK。代码如下:

#include<iostream>
using  namespace std;
 class  A
 {
 public:
     static  A * Construct(int  n)
     {
         A *pa=new A;
         pa->num = n;
         cout<<"num  is:"<<pa->num<<endl;
         return pa;
     }
     static  void Destruct(A * pIntance)
     {
         delete  pIntance;
         pIntance = NULL;
     }
 private:
     A(){}
     ~A(){}
 public:
     int num;
 };
 void  main()
 {
     A *f=A::Construct(9);
     cout<<f->num<<endl;
     A::Destruct(f);
 }

注意:上面的代码中,我们在static function里调用了nonstatic constructor。这是完全可以的。下面的话引自stackoverflow:” You can call a constructor from anywhere. If you couldn't call a constructor without an instance, how would you get any instances in the first place?You've probably called them from plain functions countless times. Static functions are no different.“


好了,这个类就这样子。按照我们的理论分析,我们的实践结果是完全成立的。

但是,这个题,它比较有挑战性,什么意思呢?难道你没有发现,咱们这水平也就仅仅有面试资格,还不可以破格录用的。
怎么啦?你可能会反问我。难道你真的没有看明白?确定没有看明白?如果是真的话,那我就告诉你吧!

咱们的类不可以实现在栈上创建对象。也就是说,仅仅只可以在堆上构建任何的一个对象,而在栈上就无能为力了。

下面的代码可以在栈上创建一个对象。

#include<iostream>
using  namespace std;
 class  A
 {
 public:
     static  A Construct(int  n)
     {
         A pa;
         pa.num = n;
         cout<<"num  is:"<<pa.num<<endl;
         return pa;
     }
	 ~A(){};
 private:
     A(){};
 public:
     int num;
 };

 void  main()
 {
     A  a = A::Construct(9);
    cout<<a.num<<endl;
 }

下面的方法比较tricky,请看实现代码:

#include<iostream>
using namespace std;
 template <typename T> 
 class Base
 {
       friend T;
 private:
       Base() {}
       ~Base() {}
 };
  
 class Finalclass : virtual public Base<Finalclass>
 {
 public :
       Finalclass() {}
       ~Finalclass() {}
 };

 class derived:public Finalclass
 {
 public: derived(){}
 };

 void  main()
 {
     Finalclass  *p=new Finalclass;  //堆上对象
     Finalclass  fs;                       //栈上对象
	// derived d;
	 int x;
	 cin>>x;
 }

How can I set up my class so it won't be inherited from?

This is known as making the class "final" or "aleaf." There are three ways to do it: an easy technical approach, an eveneasier non-technical approach, and a slightly trickier technical approach.

The (easy) technical approach is to make the class's constructorsprivate and to use the Named Constructor Idiom to create the objects. No onecan create objects of a derived class since the base class's constructor willbe inaccessible. The "named constructors" themselves could return bypointer if you want your objects allocated by new or theycould return by valueif you want the objects created on the stack

The (even easier) non-technical approach is to put a big fat uglycomment next to the class definition. The comment could say, for example,//We'll fire you if you inherit from this class or even just /*final*/ classWhatever {...};. Some programmers balk at this because it is enforced by peoplerather than by technology, but don't knock it on face value: it is quiteeffective in practice.

A slightly trickier technical approach is to exploit virtual inheritance. Since the most derived class's ctor needs to directly call thevirtual base class's ctor, the following guarantees that no concrete class caninherit from class Fred:

class Fred;
 
class FredBase {
private:
  friend class Fred;
  FredBase() { }
};
 
class Fred : private virtual FredBase {
public:
  ...
};

Class Fred can access FredBase's ctor, since Fred is a friend ofFredBase, but no class derived from Fred can access FredBase's ctor, andtherefore no one can create a concrete class derived from Fred.

If you are in extremely space-constrained environments (such as anembedded system or a handheld with limited memory, etc.), you should be awarethat the above technique might add a word of memory to sizeof(Fred). That'sbecause most compilers implement virtual inheritance by adding a pointer inobjects of the derived class. This is compiler specific; your mileage may vary.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值