Effective C++ 随笔(2)
条款5 了解c++默默编写并调用哪些函数
编译器自动生成的copy 构造函数,copy赋值操作符,析构函数,构造函数,这些都是public和inline的,此处inline的意思是他们的定义都是在头文件当中的
假设有一个引用类型的数据成员,那么上面的赋值操作是不对的,因为引用不能改变
条款6 如不想使用编译器自动生成的函数,就该明确拒绝
上面的赋值构造函数,赋值操作符都可以有编译器自动生成,为了拒绝使用上面两种函数,可以创建一个将这种函数定义私用成员的类,从而不会使用这些函数
class Uncopyable {
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
} class myclass: private Uncopyable{ };
条款7 为多态基类声明virtual 析构函数
声明为virtual
应该经析构函数声明为virtual,从而在多态调用时可以层层将各个类层次的资源析构干净,防止内存的泄露等问题
在某些类里声明纯虚析构函数很方便。纯虚函数将产生抽象类——不能实例化的类(即不能创建此类型的对象)。有些时候,你想使一个类成为抽象类, 但刚好又没有任何纯虚函数。怎么办?因为抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单: 在想要成为抽象类的类里声明一个纯虚析构函数。
这里是一个例子:
class awov {
public:
virtual ~awov() = 0; // 声明一个纯虚析构函数
};
这个类有一个纯虚函数,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:
awov::~awov() {} // 纯虚析构函数的定义
这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。 这就是说,即使是抽象类,编译器也要产生对~awov的调用,所以要保证为它提供函数体。如果不这么做,链接器就会检测出来,从而在程序的运行时刻报错。
没有必要声明为virtual
有时是没有必要声明为virtual的,因为使用多态的缺点会生成v-table,从而增加编译的复杂度,同时是程序变大,变大的程序在一些内存比较紧缺的嵌入式设备上无法加载进入内存。
有下面几种情况没有必要声明为virtual
一、所有方法为static,则不会存在类的概念,从而已不存在析构的问题
二、虽然使用继承,但是实现为多态的方式,也就是不会通过基类的引用指向继承类(指向继承类时的析构函数调用关系为,首先调用继承类,再去调用base类;构造函数相反)。也就是,此时只能是使用基类的引用指向基类,派生类的引用指向派生类。
上述两种情况都不需要在析构函数上加virtual关键字。
条款9:决不在构造析构过程中调用virtual函数
在构造函数中虚函数都不是虚函数,因此在使用多态是就会出现问题,假设首先对
条款10 为了实现连锁赋值,赋值操作符必须返回一个引用,指向操作符左侧的实参
widget& operator=(const Widget& rhs){
......
return *this;
}
条款12:赋值对象时勿忘其每一部分 当编写一个copying函数时,应该做到两点:
(1)赋值所有的local变量成员
(2)调用所有base class的copying函数
因为要对一个对象进行赋值,同时也要赋值他的父类中的成员对象,但是这些成员对象有时是private的无法直接访问,这是就需要通过父类的copying函数来进行 例如:
//base class
class class1{
public:
class1(const class1& c);
class1& operator=(const class1&);
private:
int p;
};
class1::class1(const class1& c1){
this->p=c1.p;
} class1& class1::operator=(const class1& c1){
p=c1.p;
return *this;
}
//derived class
class class2:public class1{
public:
class2(const class2&);
class2& operator=(const class2&);
private:
int pp;
}; class2::class2(const class2& c2):class1(c2),pp(c2.pp){
} class2& class2::operator=(const class2* c2){
class1::operator=(c2);
pp=c2.pp;
return *this;
}
Effective C++ 随笔(2)的更多相关文章
- Effective C++ 随笔(5)
条款27:尽量稍作转型动作 const_cast:常量性移除 dynamic_cast:安全向下转型 reinterpret_cast: static_cast: 如在子类当中享调用父类当中的某个方法 ...
- Effective C++ 随笔(4)
条款21:必须返回对象时,别妄想返回其reference 例子: Raional类可以执行有理数的一些运算,并且使用heap内存申请 并且其operator*函数为 const Rational&am ...
- Effective C++ 随笔(3)
条款12: 以对象管理资源 两种只能指针: std:auto_ptr<> 当使用copy操作室,原先的智能指针指向为null std:tr1:share_ptr<int> sp ...
- Effective C++ 随笔(1)
条款一 c++ 为一个语言联邦 1.四个层次 C:blocks,语句,预处理器,内置数据类型,数组,指针 面向对象的C++:封装,多态,继承 Template C++ STL 条款二 尽量以const ...
- Effective Modern C++翻译(1):序言
/*********************************************************** 关于书: 书是我从网上找到的effective Modern C++的样章,内 ...
- 小王子浅读Effective javascript(一)了解javascript版本
哈哈,各位园友新年快乐!愚安好久没在园子里写东西了,这次决定针对javascript做一个系列,叫做<小王子浅读Effective javascript>,主要是按照David Herma ...
- Linux随笔-鸟哥Linux基础篇学习总结(全)
Linux随笔-鸟哥Linux基础篇学习总结(全) 修改Linux系统语系:LANG-en_US,如果我们想让系统默认的语系变成英文的话我们可以修改系统配置文件:/etc/sysconfig/i18n ...
- AI人工智能系列随笔
初探 AI人工智能系列随笔:syntaxnet 初探(1)
- 【置顶】CoreCLR系列随笔
CoreCLR配置系列 在Windows上编译和调试CoreCLR GC探索系列 C++随笔:.NET CoreCLR之GC探索(1) C++随笔:.NET CoreCLR之GC探索(2) C++随笔 ...
随机推荐
- TableViewCell去除选中效果
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableV ...
- centos7下swoole1.9的安装与HttpServer的使用
一.下载swoole源码包 https://github.com/swoole/swoole-src/releases 如:swoole-src-1.9.6.tar.gz 二.编译安装 > yu ...
- 操作系统的发展史 day36
什么是操作系统 可能很多人都会说,我们平时装的windows7 windows10都是操作系统,没错,他们都是操作系统.还有没有其他的? 想想我们使用的手机,Google公司的Androi ...
- css 边距等常用设置
前端知识 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- taglib简介
在 JSP最佳实践的 上一期,您学习了一种基于scriptlet的技术,这种技术被用来将上次修改的时间戳添加到JavaServer Page(JSP)文件中.不幸的是,比起它所提供的短期利益,scri ...
- laravel框架一次请求的生命周期
第一件事所有的请求都会被web服务器(Apache/Nginx)导向public/index.php文件.index.php文件载入Composer生成的自动加载设置,然后从bootstrap/app ...
- 从matlab中导出下载到的轨迹数据
我从该网址(http://www.ee.cuhk.edu.hk/~xgwang/MITtrajsingle.html)下载到了一些轨迹数据. 网页中简单说明了轨迹数据的由来:原始数据是在一个停车场上方 ...
- hdu 3415(单调队列) Max Sum of Max-K-sub-sequence
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3415 大意是给出一个有n个数字的环状序列,让你求一个和最大的连续子序列.这个连续子序列的长度小于等于k. ...
- Android.InstallAntOnMacOSX
在Mac OS X上安装ant http://blog.csdn.net/crazybigfish/article/details/18215439
- System.Runtime.InteropServices.COMException: 检索 COM 类工厂中 CLSID 为 {0002E510-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80040154
这个问题困恼我好几天了,今天终于解决. 开始我在网上左百度右google,都没搜到最终的解决方案,今天我把解决方案贴出来,以供大家分享! 网上有些是报80070005错误的,跟我这个80040154错 ...