C++中定义使用受限的类
1、只能在堆上使用的类
栈上对象通过自动调用析构函数释放空间,将该类的析构函数定义为private就可以阻止其被自动调用,从而阻止在栈上使用该类的对象,为了避免资源泄漏问题,在堆上使用该类的对象时我们必须手动调用其析构函数。代码如下。
#include <iostream>
using namespace std;
class CHeapOnly {
public:
CHeapOnly() {
cout << "Constructor of CHeapOnly" << endl;
}
void Destroy() const {
delete this;
}
private:
~CHeapOnly() {
cout << "Destructor of CHeapOnly" << endl;
}
};
int main() {
CHeapOnly* pHeap = new CHeapOnly;
pHeap->Destroy();
//CHeapOnly objHeap; //error
return 0;
}
2、只能在栈上使用的类
堆上对象的析构需要调用delete operator,delete operator会调用析构函数,然后调用operator delete,operator delete是函数且可以被重载,将operator delete定义为private就可以阻止堆上对象的析构,从而阻止其在堆上使用。类似的,我们可以将operator new定义为private阻止堆上创建该类的对象,因为堆上创建对象需要调用new operator,new operator会调用operator new,然后调用类的构造函数。
#include <iostream>
using namespace std;
class CStackOnly {
public:
CStackOnly() {
cout << "Constructor of CStackOnly" << endl;
}
~CStackOnly() {
cout << "Destrucotr of CStackOnly" << endl;
}
private:
void* operator new(size_t size) {
}
void operator delete(void * pointee) {
}
};
int main() {
CStackOnly objStack;
//CStackOnly* pStack = new CStackOnly; //error
return 0;
}
3、不能被继承的类
构建派生类对象时会调用基类的构造函数,将一个类的的构造函数定义为private就可以阻止被继承。那么如何生成该类的对象呢?这时可以一个工厂方法。
还有一种方法类似boost::noncopyable,代码如下,我们需要使用虚基类的性质,虚基类的构造是由most derived class负责,具体请参考《深度探索C++对象模型》第210页,书中指出“constructor的函数本体因而必须条件式地测试传进来的参数,然后决定调用或者不调用相关的virtual base class constructors”,也指出“只有当一个完整的class object被定义出来时,它才会被调用;如果object只是某个完整object的subject,它就不会被调用”,换句话说就是most-derived class才会调用虚基类的构造函数。
#include <iostream>
using namespace std;
class CNonderivable;
class CNonderivableHelper
{
private:
friend class CNonderivable;
CNonderivableHelper(){};
};
class CNonderivable:private virtual CNonderivableHelper {
public:
CNonderivable(){};
~CNonderivable(){};
};
class Derived:public CNonderivable {
};
int main() {
CNonderivable x;
//Derived y; //error
return 0;
}
4、不能执行拷贝或赋值的类
拷贝和赋值需要调用拷贝构造函数和赋值运算符,如果将这两个函数声明为private就可以阻止执行拷贝或赋值,更好的方法是像boost::noncopyable一样,或者使用C++中的delete关键词,然后继承这个类。需要注意的是,将拷贝构造函数和赋值运算符声明为private的,只能阻止用户代码不能拷贝这个类型的对象,但是友元和成员函数仍旧可以拷贝对象,为了阻止友元和成员函数进行拷贝,我们只能声明不能定义它们。
//方法1
class Uncopyable {
public:
Uncopyable() {}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
//方法2
struct NonCopyable {
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
//使用时继承上面两个类中的某一个即可
C++中定义使用受限的类的更多相关文章
- java中定义一个CloneUtil 工具类
其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...
- ES6 class类中定义私有变量
ES6 class类中定义私有变量 class类的不足 看起来, es6 中 class 的出现拉近了 JS 和传统 OOP 语言的距离.但是,它仅仅是一个语法糖罢了,不能实现传统 OOP 语言一样的 ...
- JPA 不在 persistence.xml 文件中配置每个Entity实体类的2种解决办法
在Spring 集成 Hibernate 的JPA方式中,需要在persistence配置文件中定义每一个实体类,这样非常地不方便,远哥目前找到了2种方法. 这2种方式都可以实现不用persist ...
- 关于Java中的几种特殊类与接口,及特殊的创建实例的方法
Java中有一些特殊的类,在教材中讲解的不深,但是确实非常有用的,这里总结一下,里面用到的有网上搜到的内容,这里表示下感谢. 一.成员内部类 成员内部类是在一个内中定义的另外一个类,这个类属于其上的类 ...
- IronPython中共享的C#基类如何向下转型
在项目中,我们使用IronPython来定义工作流脚本来以应对科研多变的需求.项目使用的主要语言仍然是C#,使用C#封装了各种基础服务与基础设施.Python脚本只使用C#提供的服务,或者说只定义了逻 ...
- 如何使用其他文件中定义的类Python
我在文件a.py中定义了一个类class A(object),现在想在b.py中的类B中某个函数中创建一个A的对象,需要如何操作呢? 我在b的头加了import a.py然后使用语句 obj = A( ...
- JS中定义类的方法
JS中定义类的方式有很多种: 1.工厂方式 function Car(){ var ocar = new Object; ocar.color = "blue" ...
- java类中定义接口
今天看到一个java类中定义了接口,写个备忘录,记录一下 package com.gxf.test; public class Test_interface { public interface sh ...
- php中定义类
<?php class Person{ //定义了一个Person类 public $name; //定义属性name public $age; //定义属性age function __con ...
随机推荐
- 你的float用对了吗
介绍 很多人都知道float是浮点类型,它不能表示数据范围内的所有数值.但是,实际使用或编码时,你又是否记得这句话呢?下面是stackoverflow中的一个问题: why does a float ...
- HDU 5692 (DFS序+线段树)
DFS获得从0到每一个顶点的距离,同时获得L和R数组.两数组为遍历时从i进入再从i出来的序列. #pragma comment(linker, "/STACK:1024000000,1024 ...
- php 缓存之 APC 和apcu
php opcode 缓存 apc. 其实,我自己的理解, php apc 缓存其实分两部分, 一部分是 缓存 类似于 java 编译的中间的 字节码, 不同于c 语言编译之后的二进制的机器码. ph ...
- Android编程中的实用快捷键
作为一个优秀的程序员,不但要能开发出漂亮的软件,也要能熟练掌握编程的技巧,包括IDE的快捷键使用.比如linux 下的VI编辑器,对于不熟练快捷键的人来说就是一个噩梦,但一旦你熟练了VI的快捷键,VI ...
- CodeForces 590B Chip 'n Dale Rescue Rangers
这题可以o(1)推出公式,也可以二分答案+验证. #include<iostream> #include<cstring> #include<cmath> #inc ...
- The 2014 ACM-ICPC Asia Regional Anshan
继续复盘下一场Regional! [A]-_-/// [B]模拟(之前每次遇到模拟.暴搜都直接跳了,题目太长也是一个原因...下次是在不行可以尝试一下) [C]数论 互质.容斥? [D]数学推导(方差 ...
- 浅谈mysql主从复制的高可用解决方案
1.熟悉几个组件(部分摘自网络)1.1.drbd —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...
- (中等) HDU 1495 非常可乐,BFS。
Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享 这一瓶可乐,而且一定要喝的和s ...
- Objective C HMAC-MD5
- (NSString*) HMACWithSecret:(NSString*) secret andString:(NSString *)str { unsigned long encode = C ...
- PHP的Cookie、Session和跟Laravel相关的几点了解
这两天通过对Cookie和Session的查找和了解,网上关于它们两个的基础知识点都是差不多的,也收藏了几篇不错的博客,同时自己做了些实验后,有了以下几点了解: 1.setcookie 这里有三个地方 ...