1~10条款

本文深入探讨了C++编程中的关键概念与最佳实践,包括语言联邦特性、泛型编程、STL库使用、预处理器替代、const关键字的有效利用、对象初始化、避免异常逃逸、多态基类的虚拟析构函数等,旨在帮助开发者提高代码质量和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*1,视C++为一个语言联邦-----------------------------------------------------------------*/
//<1>:C++是以C为基础,区块(blocks)、语句(statements)、预处理(preprocessor)、
//    内置数据类型(built-in data types)、 数组(arrays)、指针(points)等统统来自于C
//<2>:C++又包含了新的,析构函数和构造(classess)、封装(encapsulation)、继承(inheritance)、
/    /多态(polymorphism)、虚函数(动态绑定)等等
//<3>:Template C++这是C++的泛型编程,是整个C++用的最多的地方
//<4>:STL是Template的程序库,它对容器,迭代器,算法,函数对象的规约有极佳的紧密配合与协调


/*2,尽量以const、enum、inline替换#define;用编译器替代预处理器---------------------------*/
#define ASPECT_RATIO 		    1.653
const   double AspectRation = 1.653                   //用常量替换上面的宏定义
const   std::string authorName("Scott Meyers")        //字符串常量定义
class GamePlayer                                //定义class的专属常量
{
	private:
		static const int Num;                   //常量声明式  
		
		enum{NumTurns = 5};                     //使用枚举,取枚举的地址是不合法的
		int scores[NumTurns];                   //使用该常量
}
const int GamePlayer::Num = 5;                  //常量的定义,在实现文件中实现,不是在头文件中

#define CALL_WITH_MAX(a, b) f((a)>(b) ? (a) : (b))      //函数宏定义操作
template <typename T>						            //使用类内联函数来替代
inline void callWithMax(const T&a, const T &b)
{
	f(a > b ? a : b);
}


/*3,尽可能使用const--------------------------------------------------------------------*/
//<1>,如果关键字const出现在星号的左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;
//     如果出现在星号两边,表示被指物和指针两者都是常量
//<2>,const修饰函数返回值
//<3>,const修饰成员函数,1:它们使class接口比较容易被理解,得知那个函数可以改动对象内容而那个函数不行,很重要
//                        2:它们使"操作const对象"成为可能,改善C++效率的根本方法以pass by referecnt-to-const(引用方式)传递对象
//                        3:两个成员函数如果只是常量性不同,可以被重载

char greeting[] = "Hello"
const char *p        = greeting;                 //数据是const,指针不是const
char * const p       = greeting;                 //数据不是const,指针是const
const char * const p = greeting;                 //数据是const,指针是const

vector<int> vec;
const vector<int>::iterator iter = vec.begin();  //iter的作用像个 T* const
*iter = 10;                                      //没有问题
++iter;                                           //错误 iter是const

vector<int>::const_iterator cIter = vec.begin(); //cIter的作用像个const T*
*cIter = 10;                                     //错误*cIter是const
++cIter;                                          //没有问题

class Rational{};
const  Rational operator* (const Rational &1hs, const Rational &rhs);   //const修饰函数返回值
Rational a, b, c;
(a*b) = c;                                                                  //不合法

class TextBlock{
	public:
		const char & operator[](std::size_t position) const         //const修饰类成员函数
		{
			return text[position];                                  //const对象
		}

		char & operator[] (std::size_t position)
		{
			return text[position];                                  //non-const对象
		}
	private:
		std::string text;
}
void print(const TextBlock &ctb)                         //此函数ctb是const
{
	std::cout << ctb[0];                                 //调用const TextBlock::operator[]
}

TextBlock tb("Hello");
const TextBlock ctb("World");
tb[0]  = 'x';                                                             //合法          
ctb[0] = 'x';                                                             //错误


/*4,确定对象被使用前已先被初始化---------------------------------------------------------*/
//<1>,确保每一个构造函数都将对象的每一个成员初始化
//<2>,赋值和初始化是有区别的
//<3>,成员初始化的顺序总是以其声明次序被初始化
class ABEntry{
	public:
		ABEntry(const std::string &name, const std::string &address, const std::list<PhoneNumber> &phones);
	private:
		std::string theName;
		std::string theAddress;
		std::list<PhoneNumber> thePhones;
		int numTimesConsulted;
}

//这些都是赋值
ABEntry::ABEntry(const std::string &name, const std::string &address, const std::list<PhoneNumber> &phones)
{
	theName     = name;                  
	theAddress  = address;
	thePhones   = phones;
	numTimesConsulted = 0;
}

//这些都是初始化
ABEntry::ABEntry(const std::string &name, const std::string &address, const std::list<PhoneNumber> &phones)
		 :theName(name),theAddress(address),thePhones(phones),numTimeConsulted(0)
{

}

//不同编译顺序带来的问题: 如果Directory比FileSystem先编译将会带来不可预知的问题
class FileSystem{
	public:
		std::size_t numDisks() const;       
}
extern FilesSystem tfs;                                        //给客户使用

class Directory{
	public:
		Directory(params);
}
Directory::Directory(params)
{
	std::size_t disks = tfs.numDisks();                       //调用tfs对象
}

//解决问题方法:使non-local static 对象被 static对象替代
//static: 1,局部静态变量:在初次运行时进行初始化工作,且只初始化一次;
//        2,全局静态变量:用来表示 不能被其它文件访问的全局变量和函数
//        3, 静态数据成员/成员函数
class FileSystem{}
FileSystem & tfs()
{
	static FileSystem fs;
	return fs;
}
class Directory{}
Directory::Directory(params)
{
	std::size_t disks = tfs().numDisks();
}


/*5,C++会默默编写并调用哪些函数----------------------------------------------------------*/
//定义一个空类
class Empty{
};
//编译器会默认声明的一些函数
class Empty{
	public:
		Empty() {}                                                  //default构造函数
		Empty(const Empty &rhs){}                                   //拷贝构造函数
		~Empty() {}                                                 //析构函数
		
		Empty & operator= (const Empty &rhs) {}                     //拷贝赋值操作符
};
Empty e1;                                                              //default构造函数
Empty e2(e1);                                                          //拷贝构造函数
e2 = e1;                                                               //赋值函数


/*6,若不想使用编译器自动生成的函数,就应该明确拒绝------------------------------------------*/
//阻止调用:拷贝构造函数,赋值函数的方法是声明函数为private而不进行定义
class HomeForSale{
	public:

	private:
		HomeForSale(const HomeForSale &);                    //只有声明,不定义
		HomeForSale & operator=(const HomeForSale &);
}


/*7,为多态基类声明virtual析构函数--------------------------------------------------------*/
//<1>,虚函数实现了C++的多态性;基类为虚函数派生类自动为虚函数
class A
{
	virtual void display()
	{
		cout << "This is A";
	}
}
class B : public A
{
	void display()
	{
		cout << "This is B";
	}
}
class C : public A
{
	void display()
	{
		cout << "This is C";
	}
}
void main(void)
{
	A x1;
	B x2;
	C x3;

	A *p = &x1;
	p->display;            //输出 This is A

	p = &x2;
	p->display;            //输出This is B

	p = &x3;
	p->display;            //输出This is C
}
//非基类virtual删除出错
class TimeKeeper
{
	public:
		TimeKeeper();
		~TimeKeeper();

};
class AtomicClock: public TimKeeper{};

AtomicClock *aClock = new AtomicClock;
TimeKeeper  *Clock  = aClock;
delete Clock;                                         //出错

class TimeKeeper
{
	public:
		TimeKeeper();
		virtual ~TimeKeeper();

};
class AtomicClock: public TimKeeper{};
AtomicClock *aClock = new AtomicClock;
TimeKeeper  *Clock  = aClock;
delete Clock;                                         //正确


/*8,别让异常逃离析构函数--------------------------------------------------------------*/

/*9,绝对不在构造和析构过程中调用virtual函数---------------------------------------------*/

/*10,令operator=返回一个 reference to *this------------------------------------------*/
// x=y=z=15; 从右赋值
class Widget
{
	public:
		Widget & operator += (const Widget &rhs)
		{
			return *this;
		}
			
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值