【C++】C++问题——类模板分离编译、函数对象、智能指针
来源:互联网 发布:中国国家图书馆软件 编辑:程序博客网 时间:2024/04/29 16:44
C++类模板的分离编译
过去很多类模板都是整个类连同实现都放在一个头文件里,像STL库就是遵循这样的策略来实现类模板的。现在的标准正试图矫正这种局面。
在实现中又许多函数模板。这意味着每个函数都必须包含模板声明,并且在使用作用域操作符的时候,类的名称必须通过模板变量来实例化。
比如一个operator=的代码:
template <typename Object>const MemoryCell <Object> &MemoryCell<Object>::operator=(const MemoryCell<Object> & rhs){ if(this != &rhs) storeValue = rhs.storedValue; return *this;}
头文件内容
将声明和实现都放在头文件中,对于类是行不通的,因为如果几个不同的源文件都有处理这个头文件的包含指令的话,就会出现重复定义函数的情况。但是,如果在头文件里的知识模板而不是真实的类,就不会有问题。
函数对象
在一个函数的编写中,需要像接受参数一样接受比较函数,用该比较函数来决定两个对象的大小。
使用这种方法的原因是,将比较的规则从对象中剥离出来,用一个比较函数来决定。
一个如传递参数一样传递函数的巧妙办法是:定义一个包含零个数据和一个成员函数的类,然后传递这个类的实例。从效果上看就是,通过将其放在对象中实现了函数的传递,该对象通常称为函数对象。
举例:
findMax函数获得第二个形参,该形参为泛型类型。为使findMax模板可以无误地扩展,泛型类型必须含有名为isLessThan的成员函数。该成员函数获得第一个泛型类型的两个形参,并返回一个bool值。
template <typename T, typename Comparator>const T & findMax(const vector<T> & arr, Comparator cmp){ int maxIndex = 0; for(int i=1;i<arr.size();i++) if(cmp.isLessThan(arr[maxIndex],arr[i])) maxIndex = i; return arr[maxIndex];}class CaseInsensitiveCompare{public: bool isLessThan(const string & lhs, const string & rhs) const { return stricmp(lhs.c_str(), rhs.c_str()) < 0; }};int main(){ vector<string> arr(3); arr[0] = "ZERbad"; arr[1] = "alligator"; arr[2] = "crocodile"; cout << findMax(arr, CaseInsensitiveCompare()) << endl; return 0;}
智能指针
包含指针的类需要特别注意复制控制,原因是复制指针时只复制指针的地址,而不会复制指针指向的对象。
当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。
智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。
管理指针成员
设计具有指针成员的类时,类的设计者必须首先需要决定的是该指针应提供什么行为。将一个指针复制到另一个指针时,两个指针指向同一对象。当两个指针指向同一对象时,可能使用任一指针改变基础对象。类似地,很可能一个指针删除了一个对象时,另一指针的用户还认为基础对象仍然存在。
大多数C++类采用以下三种方法之一管理指针成员:
- 指针成员采用常规指针型行为。这样的类具有指针的所有缺陷但无需特殊的复制控制。
- 类可以实现所谓的“智能指针”行为。指针所指向的对象时共享的,但类能够防止悬垂指针。
- 类采用值型行为。指针所指向的对象时唯一的,由每个类对象独立管理。
悬垂指针
具有指针成员且使用默认合成复制构造函数的类,因为类的复制时,直接复制指针。用户必须保证只要类对象存在,该指针指向的对象就存在。如果之前指向的对象不再存在了,此类指针称为悬垂指针。结果未定义,往往导致程序错误,难以检测。我们可以引入智能指针来防止悬垂指针的出现。
关于智能指针的具体内容请移步智能指针类和OpenCV的Ptr模板类
non-const成员函数调用const成员函数
在operator[]函数的编写中,我们要做的其实是实现其机能一次,并使用它两次。
你必须令其中一个调用另一个。这促使我们将常量性转除。
当const operator[]完全做了non-const版本该做的一切时,如果将返回值的const转除是安全的,因为不论谁调用non-const operator[]都一定有个non-const对象,否则就不能调用non-const函数。所以令non-const operator调用其const函数式一个避免代码重复的安全做法。
class A{public: const char& operator[](std::size_t position) const { ... ... return text[position]; } char& operator[](std::size_t position) { return const_cast<char &>( static_cast<const A&>(*this)[position] ); }private: std::string text;}
要让non-const operator[]调用const operator[],但non-const operator[]内部如果只是单纯调用operator[],会递归调用自己。所以我们必须明确指出调用的是const operator[]。这里将*this从原始类型A&转型为const A&。这样为 *this 添加const。这里我们使用static_cast进行安全转型。
第二次则是从const operator[]的返回值中移除const。这里只能借助const_cast完成。
如果在const函数内调用non-const函数,就会改变对象的逻辑状态,所以const成员函数调用non-const成员函数是一种错误行为;而non-const成员函数本来就可以对其对象做任何动作,所以在其中调用一个const成员函数并不会带来风险。
转载请注明作者Jason Ding及其出处
Github博客主页(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
百度搜索jasonding1354进入我的博客主页
- 【C++】C++问题——类模板分离编译、函数对象、智能指针
- Effective c++--智能指针 & 函数模板
- c++—智能指针
- C++——智能指针
- 【C++】为什么模板不支持分离编译
- c++-模板不支持分离编译错误分析
- 【c++】模板为什么不支持分离编译
- c++:为什么模板不支持分离编译?
- C++——函数模板和函数指针
- 【C++】智能指针类和OpenCV的Ptr模板类
- [C++]模板类的声明与实现分离问题
- C++:Boost智能指针——scoped_ptr
- C++——智能指针简介
- C++——模版:智能指针auto_ptr
- C++——模版:智能指针smart_ptr
- 普通对象智能指针模板类
- Effective C++——》条款17:以独立语句将newed的对象置入智能指针
- 模板函数的分离编译
- PAT 1001
- 如何在应用系统中实现数据权限的控制功能
- Count and Say 数字统计
- leetcode--Excel Sheet Column Number
- UVA - 11987 Almost Union-Find 并查集
- 【C++】C++问题——类模板分离编译、函数对象、智能指针
- 局域网渗透工具合集
- 1015. 德才论 (25)
- Length of Last Word 最后个字符长度
- 参考了btsource、jbittorrent实现和utorrent机制
- Context,什么是Context?
- 导航栏视图控制器(navigation controller)
- A*算法
- windows上安装mingw和配置autoconf