c++编程技巧与规范

2.全局对象的构造顺序

千万不要在构造一个全局对象的时候,用到另一个全局对象,因为无法确定另一个全局对象什么时候构造

A(const A& tempobj) //拷贝构造函数  
{
}
A& operator = (const A& tmpobj)//操作符
{
	if(this == tmpobj)
	{
		return *this;
	}
}

_nmsp1::A obj2 = obj1;   //拷贝构造函数  
obj2 = obj1; //赋值操作符 
  1. 如果程序员在子类中写了自己的拷贝构造函数和拷贝赋值运算符
    那么对于父类中的拷贝构造函数和拷贝赋值运算的调用就变成了程序员自己的责任。
B(const B& tempobj) :A(tempobj)
{
}
B& operator = (const A& tmpobj)//操作符
{
	if(this == tmpobj)
	{
		return *this;
	}
	A::operator = (tmpobj);
	return *this;
}
#include <crtdbg.h>

int main()
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF);
}

控制台输出 是否有内存泄漏

  1. 做父类应该有个虚析构函数
  2. 子类不要遮蔽父类中的普通成员函数
  3. 纯虚函数 让子类继承父类的成员函数接口
    3.1 纯虚函数所在的类变成了抽象类,抽象类时不能用来生成该类对象的
    父类 virtual void work() = 0;
    子类类 virtual void work()
    {
    }
  4. 虚函数 让子类继承父类的成员函数接口和实现,子类还可以提供自己新的实现
    父类 virtual void work()
    {
    }

子类 virtual void work() //或 不实现
{
}

class B:public A {};
class C:public B {};
void func (A tempa)
{cout << "A "<< endl;};
void func (C tempc)
{cout << "C "<< endl;};

B tempb;
C tempc;
func(tempb);
func(tempc);
则 输出 A C

namespace _nmsp1
{
template <typename T, typename U>
class smap
{
public:
void insert(vonst T& key, const U& value)
{
if (container.find(key) ! = container.end())
container.insert(std::make_pair(key, value));
}
private:
std::multimap <T, U> container;
}
}
class::smap <int, int> tmpsmap

禁止拷贝构造和禁止赋值操作符
A(const A& temp) = delete;
A& operator = (const A&) = delete;
或者
private:
A(const A& temp) {};
A& operator = (const A&) {return *this};

不要随便public继承一个不熟悉的类。 final加到类后面 就不支持被继承。
只有父类指针指向子类对象(父类引用绑定子类对象),这种多态形式的代码存在的时候,父类才有必要写一个虚析构函数(public修饰)

a)如果子类public继承父类,那么父类指针可以指向子类对象
b) 如果子类private或protected继承父类,那么父类指针不可以指向子类对象
c) 如果让父类指针指向子类对象,那么就需要用public继承,这个时候父类就需要提供虚析构函数

总结
a) 一般如果父类中有其他虚函数,意味着会按照多态的方式来使用该父类,也就是一般会存在父类指针指向子类对象的情形.
//那么此时父类中应该有一个public修饰的虚析构函数
b) 如果代码中并不会出现父类指针指向子类对象(父类引用绑定子类对象),那么父类中不需要有虚析构函数
//同时,在文档中应该明确告知开发者不应该public继承该类,而应该尽量使用private
c) 如果某个类不作为父类使用,那么不应该在该类中存在虚析构函数

不要在类的构造函数与析构函数中调用虚函数
在这里插入图片描述
a)如果在父类的构造函数中调用了一个子类的虚函数是无法做到的,因为执行到父类的构造函数体时对象的子类部分还没构造出来,
b)如果在父类的析构函数中调用了一个子类的虚函数是无法做到的,因为执行到父类的析构函数体时对象的子类部分已经销毁

  1. 大部分纯虚函数没有实现体,但纯虚析构函数是个特例,为了释放资源等,所以一般要有实现体
class PVC
{
	public virtual  ~PVC () = 0;
};

PVC::~PVE()
{
} 
  1. shared_ptr

shared_ptr myp(new int(5));
int icount = myp.use_count();//一个对象有几个share_ptr 指向它
cout << "icount = " << icount << endl;
{
shared_ptr myp2(myp);
icount = myp2.use_count();
cout << "icount = " << icount << endl;
}
icount = myp.use_count();
cout << "icount = " << icount << endl

输出 1 2 1

  1. string

实现方式 eager-copy ,copy-on-write,small string optimizationw

string str1 = “I Love China!”;
string str2 = str1;

在这里插入图片描述
拷贝赋值运算符:
如果一个类中包含有指针成员,那么一般都需要手工为该类书写拷贝构造函数和拷贝赋值运算符。否则一般都会出现问题。

class A
{
A() {}

~A() {}

A (const A &) {}

A & operator = (const A &) {}
}
class Widget
{
public :
Widget()
{
	pa[0] = &Widget::f;
	pa[1] = &Widget::a;
	pa[2] = &Widget::b;
	pa[3] = &Widget::c;
}

void select(int idnx)
{
	(*pa[indx])();
}

private:

void f() {cout << "f" << endl}
void a() {cout << "a" << endl}
void b() {cout << "b" << endl}
void c() {cout << "c" << endl}
}


//void (Widget::*pa[4])() = {f, a, b, c}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值