`
为心中梦想挥剑的那一刹那
  • 浏览: 6829 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

c++程序设计梳理(谭浩强)9章

 
阅读更多

 天气凉了,今天一气儿睡到下午3点,天气一冷,这觉就多起来了。中午时分的时候,优酷土豆来了个电话,我过了笔试让我去面试。刚开始我还有点点激动来着,可听到他们说是要去帝都面试,顿时情趣全无。他又来了个,说是路费他们承担,照样还是提不起来兴趣。尼玛,大成都离帝都这么老远,让我这几天大老远的跑去,就为了个面试?18号回家,我看还是算了吧。昨晚把《饥饿游戏》第一部看了,唯一喜欢的,就是那个女主。完全有我心中完美女性的影子,再加女主的面容是那种婴儿肥类型的可爱,又中了我的胃口。打算今天写完这章,马上把第二部补了,12号上映第三部,果断imax去!
 从今天开始进入c++核心特性的总结梳理:面向对象的程序设计。其实谭浩强在这本书中面向对象全面的铺开,只用了6章,前面8章可以说都是在铺垫。虽然少,但是我认为,这本书,完全可以成为国内c++教学的经典中的经典。虽然还是有疏漏,可是在所能触及的范围之内,把我们能接触到的,国内的,完完全全的以通俗易懂、简约大方、文字清晰、代码易读等方式展现了出来,所以我认为,中国当今的计算机高等教育,在大一无论是何种类型的大学,都要用这本书,真的是受益匪浅!
Chapter9
->关于类和对象的进一步讨论
1、类的初体验:

class Box{
public:
	Box(int,int,int);//构造函数的声明
	Box() :height(1), wight(2), lenght(3){}//使用了参数初始化表,此种构造参数是较长用到的,要看得懂
	//Box(int a=0,int b=2,int c=3);//这里使用了默认参数的构造函数,但是如果我们要申请对象,例如:Box a,那编译器将不知道使用上面的Box()构造函数还是用这个,所以出现歧义,不正确
	int vollume();//公有函数的声明,这里是求体积
private:
	int height;
	int wight;
	int lenght;
};
Box::Box(int a, int b, int c){//类外实现构造函数
	this->height = a;//这里用到this指针,指向本类中的属性
	this->lenght = b;
	this->wight = c;
}
int Box::vollume(){//类外实现公有函数
	return this->height*this->lenght*this->wight;
}

注意:我们不应该同时使用类的构造函数的重载与拥有默认参数的构造函数,这样容易出现二义性(函数也如此)。


2、构造函数与析构函数:
(1)调用顺序这两个是刚好相反的。在初始化对象的时候,构造函数的调用是从基类到派生类;在对象销毁的时候,调用析构函数,调用顺序是从派生类到基类。
(2)构造函数不能使虚函数(后面会详细的总结虚函数的东西),而析构函数,在有继承关系的体系中最好是虚函数。原因是构造函数要先调用基类的构造函数,再调用派生类的构造函数,如果要是虚函数,那么会只调用基类的或者是派生类的,这样下来构造不完全;析构函数之所以最好设置为虚函数,是因为要保证释放的完全性。在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。
(3)析构函数中不要抛异常。虽然语法上面没有错,但是会带来重大隐患。如果一定要抛的话,最好不要让异常跑出,在析构函数内部捕获。 阻止异常传递到析构函数外有两个原因,第一能够在异常转递的堆栈辗转开解(stack-unwinding)的过程中,防止terminate被调用。第二它能帮助确保析构函数总能完成我们希望它做的所有事情。


3、共用数据的保护:(这个地方是const的在类上面的详尽用法,很繁琐,我梳理一下)
(1)常对象、常成员函数、常数据成员。

数据成员 非const成员函数 const成员函数
非const的数据成员 可以引用,也可以改变值 可以引用,但不可以改变值
const数据成员 可以引用,但不可以改变值 可以引用,但不可以改变值
const对象的数据成员 不允许引用和改变值 可以引用,但不可以改变值

其中常对象的是用来保护数据成员用的,除了常对象中的const类型的数据成员函数能引用数据成员,其他的都不行;常成员函数的声明方式:void function() const;常数据成员只能通过构造函数的参数初始化表对常数据成员进行初始化,例如:
Time::Time(int h)
{
 hour=h;//如果hour是常数据成员的话,这样的初始化非法!
}
Time::Time( int h ):hour(h){}//正确
(2)指向对象的常指针、指向常对象的指针变量。
指向对象的常指针:Time * const ptr1,这样的情况,那ptr1这个指针一旦初始化,之后就能能再修改其指向,例如
ptr1 = &time;//初始化
ptr1 = &t2;//错误,因为常指针不能修改其指向
指向常对象的指针变量:这里对于指向常对象的指针变量有三个关键性的解说
①如果一个变量已被声明为常变量,只能用指向常变量的指针变量指向他,而不能用一般(指向非const型的变量)指针变量去指向他;
②指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为const的变量。此时不能通过此指针变量改变该变量的值;
③如果函数的形参是指向非const型变量的指针,实参只能用指向非const变量的指针,而不能用指向const变量的指针,这样,在执行函数的过程中可以改变形参指针变量所指向的变量的(也就是实参指针所指向的变量)值。总之一句话就是:指向常变量的指针变量可以指向const和非const型的变量,而指向非const型变量的指针变量只能指向非const的变量。
指向常对象的的指针变量类似:
①如果一个对象已被声明为常对象,只能用指向常对象的指针变量指向他,而不能用一般的指针变量去指向他。例如
const Time t;
Time t2;
const Time *p;
p=&t;//正确
p=&t2;//错误
②如果定义了一个指向常对象的指针变量,并使他指向一个非const的对象,则其指向的对象是不能通过指针来改变的
。例如
Time t;
const Time t2;
const Time * p = &t;
t.hour = 19;//正确,因为是常对象
p->hour=19;//错误,因为是指向常对象的指针
(3)常引用:void function(const Time &t),这样在function函数当中我们就不能修改对象t的值了。在c++程序设计过程中,我们经常用到常指针和常引用做函数参数,主要就是保证数据不会被修改。


4、对象的复制与对象的赋值:这两个有概念和本质的不同,其中对象的复制是在一个对象初始化了,用这个初始化的对象去完全复制的初始化另外一个对象,例如
Time t1;
Time t2(t1);//或者是:Time t2=t1
这样;而对象的赋值是两个都初始化了的对象进行赋值,例如
Time t1,t2;
t1=t2;
这样。(我们要注意识别具体在哪是对象的复制,在哪是对象的识别,例如在函数返回值的时候就是对象的复制等。这个问题在今年笔试中也考到过。因为是这种细节细致的知识点,各大公司的笔试都愿意出!)
5、静态数据成员、静态数据成员函数。
(1)静态数据成员:
①在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,他可以被引用;
②静态数据成员是在程序编译时被分配空间的,在程序结束时才释放空间;
③静态数据成员可以初始化,但只能在类体外进行初始化。
(2)静态数据成员函数:
①这种成员函数内部并没有this指针。(这点很关键)所以在不指定对象的名的情况下,在这种成员函数之中不能对对象的数据成员进行访问。
②这种数据成员函数主要就是对静态数据成员进行处理的函数。
6、友元函数与友元类的问题。友元函数与友元类能访问类中的private成员和protected成员。他的用处主要是在后面的运算法重载当中用的比较多。
p.s:模板(template<class 类型参数名>)这个东西我想在后面的《c++primer》当中详细梳理,谭浩强这本书并没有很深入的写这个点。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics