Effective C++ 26,27,28

26.当心潜在的二义性。

一些潜在的二义性的例子:

class A{
public:
	A(const B&);
};
class B{
public:
	operator A() const;
};
void f(const A&);

一般情况下,这样写不会出错,但当调用f函数传入一个 B的对象b时,就会发生二义性错误,b既可以通过A的构造函数获得一个A的对象,也可以通过B的类型转换运算符来将b变成一个A的对象再使用,而编译器不知道应该使用哪种方法。这是一个潜在的二义性,其一般情况下正常无误。

还有更简单一点的二义性,当两个函数重载时,如 f(int ) f(char);,而传入一个double类型的参数d时,就会发生二义性,编译器不知道应该将d转换为char类型还是int类型。

多继承中充满了二义性的可能。如多个基类具有同名的函数或数据成员,就必须指明成员的基类来消除二义性,即使一些成员在其所在的基类中是私有的,即派生类无法访问,但这还是有二义性的错误。为什么消除 对类成员的引用产生的二义性时不考虑访问权限:改变类成员的访问权限不应该改变程序的含义,即当类定义好之后,改变成员的访问属性会导致一些访问出错或这依旧正常,这是正确的,而如果改变访问属性改变了程序的含义(如A 类B类派生 出C类,c中一个函数调用两个基类中同名的成员,如果 消除二义性时考虑了访问权限, 当A中成员为公有,b中成员为私有时,c中函数调用a中成员,而改变了访问权限,a中为私有,b中为共有,就会导致c中函数调用b中成员,改变了程序的含义,但是对于程序猿,却一无所知。如果保护考虑的话,会出现访问出错,会提示程序员进行修改)
所以最好还是显示的消除二义性。

27.如果不想使用隐式生成的函数就要显式的禁止它。

对于这些不想使用的函数禁止它,原因很简单,为了之后更容易更新和维护,当你现在在写这个类时,你没有禁止这些不应该使用的函数,你记得这些事情,所以你自己不会犯这些错误,但当过了很长一段时间,或者其他人接替了你的工作来对你的代码进行升级和维护时,这个没有禁止的功能就很有可能出现在一些地方让你措手不及。所以最好还是禁止这些不应该使用的函数。

对于类中一些函数,编译器会隐式的自动生成,如缺省的无参构造函数,赋值 =,复制构造函数等,要禁止这些函数,一个简单的方法就是声明这些函数为private ,显示声明防止编译器自动生成,而private防止其他人调用。

但这样还是不安全,成员函数和 友元函数还是可以调用这些私有函数。这样就只去声明这些函数,而不去定义函数体,当其他函数调用时,编译器就会在链接时报错。

28.划分全局名字空间。

使用命名空间来解决命名冲突。对命名空间之前有过一些研究:c++命名空间,命名空间是可以嵌套的。

命名空间的使用方式有三种, using namespace xxx;之后所有的xxx命名空间的成员都可以直接访问。 using xxx::成员 ,对于xxx命名空间中的这个成员可以直接使用。xxx::成员,在一个地方使用xxx命名空间中的这个成员。

可以使用struct来近似实现namespace , 先创建一个结构用以保存全局符号名,然后将这些全局符号名作为静态成员放入结构中。访问时加上struct的名作为前缀 ,与命名空间类似。

struct sdm{
	static const double VERSION ;
	class A{
	public:
		void  f(){cout<<"SDM"<<endl;}
	};

};
const double sdm::VERSION = 1.0;
class A{
public:
	void f(){cout<<"GLOBEL"<<endl;}
};
int main(){
	cout<<sdm::VERSION;
	sdm::A sdma;
	A a;

对于类型名,可以显式地去掉空间引用:

typedef sdm::A A;

对于函数,一般返回一个函数的常指针:

	sdm::A& (* const getA)()= sdm::getA;
	sdm::A& (& getA)() = sdm::getA;//返回函数的引用
时间: 2024-08-23 23:58:47

Effective C++ 26,27,28的相关文章

WCF 入门(25,26,27,28)

前言 项目赶时间,工期紧,熬过这段时间应该就好了吧.希望如此. 今天把自己那部分写的差不多了,回来和小伙伴一起又看了一遍<夏洛特烦恼>,还挺好看的,明天继续加班,do it. 第25-28集 第25集讲的是如何用winform来host 一个WCF service. 第26集讲什么是windows 服务 第27集讲用windows 服务来host 一个WCF service. 第28集讲用windows 服务来host 一个WCF service的优缺点. 用console,winform 或

EC读书笔记系列之14:条款26、27、28、29

条款26 尽可能延后变量定义式的出现时间(Lazy evaluation) 记住: ★尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率 ---------------------------------------------------------------------- 举例说明: std::string encryptPassword( const std::string &password ) { using namespace std; string encrypt

冲刺阶段第八天,4月26,27,28日。

这三天做的事: 整合代码比想象中的要难,每日抽出一个多小时,将近四个小时才完成的工作.不仅添加了注释,还把各个窗口串在了一起,微调了界面. 数据库连接部分在运行前连接一次,避免登录时卡顿. 明天要做的事: Table表在第一次声明后再次调用,虽然显示的事第二次的数据,但切换页面再切换回来,就回到了第一次的样子.

习题 2-1 位数 2-2 水仙花数 2-3 韩信点兵 2-4倒三角形 2-6 调和级数 2-7近似计算 2-8 子序列的和

2-1 位数 #include<stdio.h> #include<math.h> int main () { int n; for (n=100; n<=999; n++) { if(n == pow(n/100,3) + pow(n/10%10,3) + pow(n%10,3) ) printf("%d\n",n); } system("PAUSE"); return EXIT_SUCCESS; } 2-2 水仙花数 #includ

07-模块:shutil,shelve,xml,hashlib,subprocess,re,ConfigParser

第1章 模块 1.1 shutil模块 1 import shutil 2 # 高级的 文件.文件夹.压缩包 处理模块 3 4 # 将文件内容拷贝到另一个文件中,可以部分内容 5 # 6 # shutil.copyfileobj(fsrc, fdst[, length]) 7 # f = open("example.log") 8 # f2 = open("新的","w") 9 # shutil.copyfileobj(f,f2) 10 # sh

信号,信号量,锁,条件变量,消息通信,共享内存,RPC (一)

在实际项目当中,经常需要把一个功能分成多个子模块实现.那么,这些子模块之间该如何关联起来呢?静态地看,模块可以看作一组完成相同功能的函数:而动态地看,模块可以是一个独立的进程.线程或者一个中断服务或者信号服务例程.根据不同的具体业务实现,它们之间可能是静态调用.动态互斥.同步.唤醒等关系.静态的调用很好实现,上层的函数调用底层的函数即可.那么,动态互斥.同步.唤醒等关系,又该如何实现呢?这就设计到我们将要讨论的信号.进程间消息通信.共享内存.线程互斥同步条件变量.RPC等手段.下面就按照Linu

常见位操作:获取,设置,清零

1 /*常见位操作:获取,设置,清零 2 * 3 * */ 4 public class BitGet { 5 /* 6 * 该函数实现获取功能 7 * 先将1左移动i位,左移动0位变成了00000001, 8 * 然后再和Num十进制12转化为二进制00001100进行&运算, 9 * 00000001 如果是左移动两位就为 00000100 10 * 00001100 00001100 11 * -------- -------- 12 * 00000000 00000100 13 * 从而

JavaEE学习之Spring Security3.x——模拟数据库实现用户,权限,资源的管理

一.引言 因项目需要最近研究了下Spring Security3.x,并模拟数据库实现用户,权限,资源的管理. 二.准备 1.了解一些Spring MVC相关知识: 2.了解一些AOP相关知识: 3.了解Spring: 4.了解Maven,并安装. 三.实现步骤 本示例中使用的版本是Spring Security3.2.2.通过数据库实现Spring Security认证授权大致需要以下几个步骤: 1.新建maven web project(因为本示例使用的是maven来构建的),项目结构如下,

C++模板元编程 - 3 逻辑结构,递归,一点列表的零碎,一点SFINAE

本来想把scanr,foldr什么的都写了的,一想太麻烦了,就算了,模板元编程差不多也该结束了,离开学还有10天,之前几天部门还要纳新什么的,写不了几天代码了,所以赶紧把这个结束掉,明天继续抄轮子叔的Win32库去. 逻辑结构和递归说白了就是做了一个If,一个For_N,If就和Excel里的If一样,For_N是把一个模板结构迭代N遍,为了所谓的方便,把If做成了宏,写起来还挺有意思的 1 template<typename TTest, typename TTrue, typename TF