C++一些特殊的类的设计

一、设计一个只能在栈上分配空间的类

重写类的opeator new 操作,并声明为private,一个大概的代码如下:

class StackOnly
{
public:
StackOnly(){/*constructor*/}
~StackOnly(){/*destructor*/};
private:
void *operator new(size_t size);
};

int main()
{
StackOnly s; //正确用法,自动变量在栈上分配内存

StackOnly * ps = new StackOnly(); //错误,全局new操作符无法调用operator new操作分配堆上内存
return 0;
}

这是一个面试题,考察的是反应速度和对知识掌握的熟悉程度,不过这个题目也有些让人迷惑,很多人想得到要改写new operator,但是却会陷入new opeator的底层怎么实现这个死循环中,误认为这个类的使用方法跟其他类一样,只是底层获取内存的方式变了,但是实际上只是不准客户使用new 这种声明方式。

二、设计一个只能在堆上分配内存的类

这题和设计一个只能在栈上分配空间的类是一样的思路,只能在堆上分配空间意味着只能以A * pa = new A(…);这种形式来获取内存,而不能通过A a;这种形式来获取。它的思路是这样的:将析构函数声明为protected 或者private ,这样的话,如果用A a ;这种内存获取方式,会导致析构函数调用出错。于是,相应的代码如下:

class HeapOnly
{
public:
HeapOnly(){/*constructor*/};
void destroy(){/*do things ought to be done by destructor*/}
private:
~HeapOnly(){/*destructor*/}
};

int main()
{
HeapOnly h ; //错误用法,无法调用析构函数
HeapOnly *ph = new HeapOnly(); //正确用法
ph->destroy(); //因为无法调用析构函数,所以要自行释放内存
}

三、设计一个不能被继承的类

很容易想到的一个思路就是将此类的构造函数私有化,那么子类就无法调用父类的构造函数了,自然无法构建父类部分,但是这样的话就不能够正常使用这个类了,因为无法正常地构造函数,只能按照如下的方法来实现一个类:

class NoInheritance
{
public:
static NoInheritance * getInstance(){return new NoInheritance();}
static void destroy(NoInheritance * pN){delete pN; };
private:
NoInheritance();
~NoInheritance();
};

int main()
{
NoInheritance *ni = NoInheritance.getInstance();
NoInheritance.destroy(ni);
return 0;
}

以上的确是个可行的方案,可惜就是用起来不太方便,利用友元的概念可以实现一个很好的不能被继承的类,如下:

class NoHeritance
{
private:
NoHeritance();
~NoHeritance();
friend class CBase;
};

class CBase:virtual public NoHeritance
{
public:
CBase();
~CBase();
private:
//members
}

虚基类最终只能由最终子类构造,CBase作为虚基类NoHeritance的友元,是可以调用其private函数的,但是友元性质不能被继承,如果Child想要继承CBase ,需要调用NoHeritance 的构造函数,这是行不通的,于是我们就构造了一个不能被继承的类。(参考:http://blog.csdn.net/doudou745/article/details/7277164

四、设计一个只能有一个实例的类

这是典型的设计模式,单例模式。如果不考虑多线程安全,大概的代码如下:

#include<iostream>
using namespace std;

class Singleton
{
public:
static Singleton * GetInstance()//通过静态公有函数获得该类的实例对象
{
if(m_pInstance==NULL)
m_pInstance=new Singleton();
return m_pInstance;
}

private:
Singleton(){}//构造函数私有化的目的是为了防止从别处实例化该类对象
static Singleton * m_pInstance;
class Garbo//删除Singleton实例的对象
{
public:
~Garbo()
{
if(Singleton::m_pInstance)
{
delete Singleton::m_pInstance;
}
}
};
static Garbo gb;//在程序结束时,系统会调用它的析构函数
};
Singleton * Singleton::m_pInstance=NULL;//初始化静态数据成员

int main()
{
Singleton *sl=Singleton::GetInstance();
return 0;
}

原文链接: https://www.cnblogs.com/obama/p/3239582.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/98644

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午4:51
下一篇 2023年2月10日 上午4:51

相关推荐