Effective c++ 18~ 25 设计与声明

18、让接口不易被误用如设计了一个Data的初始化接口:Data(int Mouth, int Day, int Year);这时可以会出现:Data(30, 12, 2015);的错误;因此可以导入新类型来预防:struct Mouth{ explicit Mouth(int M):mouth(M){}; int mouth;}这里接口可以成为:Data(co
摘要由CSDN通过智能技术生成

18、让接口不易被误用

如设计了一个Data的初始化接口:Data(int Mouth, int Day, int Year);

这时可以会出现:Data(30, 12, 2015);的错误;因此可以导入新类型来预防:

struct Mouth
{
	explicit Mouth(int M):mouth(M){};
	int mouth;
}

这里接口可以成为:

Data(const Mouth& m, const Day& d, const Year& y);

Data(M(12), D(25), Y(2015));


19、类的设计应该想到的问题


20、以const &代替值传递

传值情况:void fun(A a); 传参时,会以另一个对象以拷贝构造函数初始化a,在退出时,会调用析构函数释放a

传const引用:则没有上述所说的构造、析构函数的调用;传const可以不用担心函数内部对该值会有改变;


传值在继承中还存在问题:如果以子类传递给一个基类,则参数初始化过程调用的只是基类的构造函数,子类部分没有被初始化,无法调用子类的函数;

class base
{
public:
	virtual int pintInt()
	{
		//...
	}
};

class derive:public base
{
public:
	virtual int printInt()
	{
		//...
	}

};

void CallPrin(base b)// 传值
{
	b.pintInt();
}
void f()
{
	derive D;
	CallPrin(D); //子类初始化基类,非引用传递,只调用了基类的printInt
}

因为引用传递的就是指针,因此对于 内置类型如int或是函数对象、STL的迭代器,传值反而更高效


21、 函数不要返回指向本地对象的指针或引用

函数返回一个指向函数内生成的本地变量的引用或是指针都是错误的;(栈上的)

derive& CallPrin()
{
	derive *pd = new derive; //局部申请的内存(堆)
	return *pd; // 返回引用
}
因为上面的返回值是动态分配的,所以用户会经常无法或忘记用delete来释放内存,而造成内存泄漏;
同样,函数也最好不要返回函数内的静态值的引用,否则会出现两次调用函数得到的返回值一样的情况;如

class base
{
public:
	int a;
	base& operator*(const base& b1)
	{
		static base b;
		cout<<"static b的值: "<<b.a<<endl;
		b.a = a * b1.a;
		return b;
	}
};

void f()
{
	base b1,b2,b3;
	b1.a = 5;
	b2.a = 5;
	b3.a = 5;
	cout<<"第一次乘的地址"<<&(b1*b2)<<" "<<(b1*b2).a<<endl;   //下面两个打印出来 的结果是一样的
	cout<<"第二次乘的地址"<<&(b3*b2)<<" "<<(b3*b2).a<<endl;
}


24、二元操作符如果要进行类型转换,应该设为非成员函数(友元)

int & operator*(const int& a, const int & b);

int c = 2*b;  //非成员函数可以进行类型转换,成员函数该式子是错误的;’













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值