博文

《继承》学习笔记(2006-10-17 21:04:00)

摘要:1.向已有的类添加了新功能后的类叫做原来类的派生,原来的类叫做新类的基类。通常基类有多个派生类。 派生类的声明语法:class Dog:public Mammal 基类必须最先声明。 2.成员变量有三种限定符:private(私有型)、public(公有型)、protected(保护型)。 保护型的变量不仅可以被自己的类所访问,也可以被该类所派生出的类的成员函数所访问。而私有成员变量只可以被自己类的成员函数访问。即使是派生类也不能访问他的基类的私有成员和函数。 3.创建派生类的对象时,首先调用基类的构造函数创建对象的基类部分,然后调用派生类的构造函数,创建派生类的部分构成整个派生对象。 删除派生类的对象时,首先调用派生类的析构函数,删除对象的派生部分,然后调用基类的析构函数,删除对象的基类部分。 4.派生类的构造函数调用基类的构造函数来初始化某些成员变量,若有的成员变量希望在派生类中初始化,而基类不做初始化,则可以重载基类的构造函数,即令基类只初始化部分成员变量,然后在派生类的构造函数中显式调用该重载的构造函数。(12.3.1节) 5.派生函数可以覆盖基类函数的实现,即在派生类函数中改变基类函数的实现。 当派生类用与基类成员函数相同的返回值和签名,但却用新的实现方法创建一个函数时,就称为覆盖了该方法。签名包括:函数名、参数表以及可能用到的关键字const。 规则:一旦覆盖了任一个重载方法,那么对这个方法的所有其他原基类函数均被隐藏了,如果不想让他们被隐藏,就必须把它们全部覆盖。 若仍想调用被覆盖的函数,那可以用域限定符(::),即基类::被覆盖的方法。 6.C++扩展了其多态性,允许把派生类的对象赋给指向基类的指针。如: Mammal *pMammal=new Dog; Dog是Mammal派生出来的一个类。这样,就可以用该指针调用Mammal类中的任何一个方法。若想调用被Dog覆盖掉的方法,则可以用虚函数来完成。 7.虚函数。在成员函数返回类型前加关键字virtual。表明该类将做为一个基类来派生其他类。 对于虚函数,并不需要在派生类中也定义为虚函数,但继续标记为虚函数是比较好的理解手段。 正确调用函数,对于6中的pMammal指针,调用基类的虚函数,若在派生类中覆盖了该函数,那么就调用覆盖函数,若没有覆盖,就调用基类的虚函数。但......

阅读全文(2613) | 评论:0

《高级函数》学习笔记(2006-10-16 21:58:00)

摘要:1.构造函数中初始化对象的成员变量。掌握这种方法。 CAT(): ItsAge(5), ItsWeight(8) {} 2.复制构造函数在每次复制一个对象时调用。所有的复制构造函数均有一个参数,即对同一个类的对象的引用。使这个引用成为常量最好,这样构造函数就不必改变传递进来的对象。如: CAT(const CAT& theCat); 3.一般的复制构造函数,执行的是成员复制,简单的将成员变量复制到新的对象中,这样容易造成内存泄漏(迷途指针)。因此,复制构造函数采取开辟新的内存区来避免这种问题的发生,这也叫深层复制。如: CAT(const CAT& rhs) {itsAge=new int;itsWeight=new int;   *itsAge=rhs.GetAge();*itsWeight=rhs.GetWeight();} 4.运算符重载。让对象之间(其实是对象的成员变量)可以直接进行加减乘除等运算。 重载前置运算符的格式:returnType operator op;这里op是要重载的运算符(+、—等)。如 void operator ++(){++itsVal;} 在生成的对象i进行自加执行简单的命令:++i; 如果要将自加后的对象赋给其他的对象,则只需修改函数返回值的类型为类对象。 几种不同的前置运算符的声明方法,注意返回值的类型: classType operator ++(){++itsVal;return classType(itsVal);} const classType& operator ++(){++itsVal;returh *this;} 在效率方面,最后一个声明语句较好。 5.后置运算符的声明。同前置运算符的区别在于加入一个整型参数。如: void operator ++(int flag){itsVal++;} 其中参数flag并不参加任何运算,只是标明是后置运算符的声明。 6.重载加号运算符。声明如下: classType operator+ (const classType& rhs){return classType(itsVal+rhs.GetVal());} 这样可以对实例化的两个对象进行加法运算。 7.赋值运算符。声明如下: ......

阅读全文(2344) | 评论:0

《引用》学习笔记(2006-10-13 21:01:00)

摘要:1.引用就是一个别名,当声明一个引用时,就必须把它初始化为另一个对象名,也就是目标。声明格式如下: int &rSomRef = someInt; 对引用的操作等同于对原对象的操作。 2.对引用进行取址运算,返回的值是目标的地址,因为引用只是目标的别名。 3.引用不能够被重新赋值。若对引用重新赋值就相当于对目标重新赋值。 引用只能是对对象的引用,而不能是对类或类型的引用。 引用不能为空,即不能像空指针一样被赋为零。 4.使用引用传递参数,不是在函数的作用域中创建一个拷贝,而是直接把原对象传递给函数。因此在函数中对引用的改变也会反映到函数外。 5.指针声明的函数:    void swap(int *x , int *y);    引用声明的函数:   void swap(int &x , int &y); 6.若要确保被传递的引用参数不被改变,则使用const指针或引用来传递。如: const Cat& Function(const Cat& theCat); 7.在同一个参数列表中同时使用引用、指针及采用值传递是合法的。 要避免将局部的对象以引用的方式返回,因为局部对象在函数作用域之外就会被删除。 对于引用,不能使用delete运算符。 8.如果被返回的对象是局部的,那么就必须采用按值传递,否则就加返回一个不存在的对象的引用。......

阅读全文(2117) | 评论:0

《指针》学习笔记(2006-10-12 21:39:00)

摘要:1.指针是保存内存地址的变量。 int *pAge=0; 值为零的指针被称为空指针。所有指针在定义时都应该被初始化。没有初始化的指针称为失控指针。 int age=50; pAge=&age; 以上是为指针赋值的完整过程。 2.对于变量,类型会告诉编译器需要多少存储器去装载。但对于指针,类型并不这样做,所有指针均是4个字节。 3.使用间接引用运算符(*)来引用指针。当一个指针被间接引用时,就读取其所保存的地址处的值。 4.指针有以下三种用途: i.处理自由存储区的数据; ii.访问类的成员数据和函数; iii.通过引用的方式向函数传递变量。 5.局部变量和函数形参位于栈中,寄存器则用于内存管理(如保存栈顶指针和指令指针),代码区位于代码区,全局变量区,其余的内存空间作为自由存储区,称为堆。 栈在函数返回时会自动清除。自由存储区在程序结束之前不会自动清除,所以在占用之后必须主动释放。 6.C++中使用关键字new来分配自由存储区中的内存。new的返回值是内存的地址,它必须被赋给一个指针。如: unsigned short *pPointer=new unsigned short; 当不在使用一块内存时,使用关键字delete,它的作用是释放内存。 7.内存泄漏。 指针本身是一个局部变量,当声明指针的函数返回时,指针的作用域也就结束了,因此被丢弃了。然而由new申请的内存不会自动释放,于是这块内存就不能被其他数据使用,这种情况就称为“内存泄漏”。因此要记得使用delete来释放内存。释放后最好将指针赋值为0,变为空指针。 另一种造成内存泄漏的情况是:在没有删除一个指针之前就对其重新赋值。如: unsigned short int *pPointer=new unsigned short int; *pPointer=72; pPointer=new unsigned short int; pPonter=84; 这时保存72的内存空间变得不可用,也没办法再去释放它。应该是再次使用时,先释放。 8.也可以在自由存储区内为类的对象分配内存。如: Cat *pCat=new Cat; 这条语句调用了默认构造函数(无参数的构造函数)。删除这类指针时,在内存释放之前会调用对象的析构函数。 也就是说,内存分配是在类对象......

阅读全文(3217) | 评论:2

《程序流程》笔记(2006-10-11 21:52:00)

摘要:1.while循环语句中的测试条件句可以是任何有效的C++语句或语句块,它也可以包括使用逻辑运算符的表达式。 2.若需要在执行while循环中的所有语句之前返回到while循环的开始处,则可以用continue语句。 若需要在满足退出循环条件之前跳出循环,则可以用break语句。 3.do...while循环在执行测试条件之前先执行循环体,保证循环体至少被执行一次。 4.for循环语句的执行过程分析 for(initilization,test,action) statement; initilization语句用来初始化counter的值,或是为循环做好准备。test语句可以是任何C++表达式,在每次进入循环体时都要对它进行测试。如果test测试为真,则执行循环体,然后执行action语句。 4.空for循环语句。若循环体内不放任何语句,也切记要放一条空语句(;)。 5.switch表达式可以是任何C++合法的表达式,但是该表达式的值的类型只能是int、char、enum这三种类型。......

阅读全文(2974) | 评论:2

《类的定义》相关笔记(2006-10-11 21:04:00)

摘要:1.一个类可以包含各种类型的变量,也可由其他的类组成。类中的变量称为成员变量或数据成员。类中的函数称为成员函数或类的方法。 2.声明一个类并没有为该类分配内存,只有定义类的对象时,才为对象分配内存。 3.为对象赋值,而不是为类赋值。例如: Cat是一个类,itAge是其成员变量,则以下程序不正确 Cat.itAge=5; 4.一个类的所有成员(数据和方法)默认时均为私有的。私有成员只有在类本身的方法内访问。公有成员则可以被类的所有对象访问。 5.构造函数可以带有参数,但不能有返回值,返回空值也不行。构造函数是一个与类同名的方法。构造函数创建并初始化类的对象。析构函数在对象撤除后清除并释放分配的内存。析构函数没有参数,也没有返回值。 如果没有为类创建构造函数和析构函数,编译器会自动创建一个,即为默认构造函数。没有参数的构造函数被称为默认构造函数。编译器创建的默认构造与析构函数不带任何参数,且不执行任何操作。 只要自己创建了构造函数,系统将不再提供构造函数。因此除非自己再创建默认的构造函数,否则程序将不会有默认的构造函数。 6.如果声明类方法为const,则该方法不能更改类任何一个成员变量的值。类方法声明为常量,如下所示: void SomeFunction() const; 良好的编程习惯是将尽可能多的方法声明为const。 7.可能通过加关键字 inline 来实现成员函数的内嵌。也可以用其他类作为自定义类的成员变量。 8.C++中结构体与类相同,只是其成员默认是公有的。但结构体没有方法。 9.类的对象在内存中的大小由类的成员变量的大小的总和来决定。类方法不占用为该对象所分配的那部分内存。 10.一个类定义了两个对象,那么两个对象可以相互访问对方的数据成员,也包括私有成员。......

阅读全文(3118) | 评论:4

《函数》笔记(2006-10-10 22:04:00)

摘要:1.函数原型(即函数声明)可以不包含参数名,而只包含函数类型。即原型中的参数名无实际意义。如: long Area(int,int); 此外,若函数未声明返回值类型,则系统默认为返回值为整型。 2.若局部变量与全局变量同名,则在局部变量作用范围内,全局变量将被屏蔽。C++中尽量不要使用全局变量,而使用静态成员变量来替代。 3.任何一个合法的C++表达式都可以作为一个函数的变元(传递给函数以作为参数),包括常量、数学和逻辑表达式以及其他可返回值的函数,即也可以使用一个函数的返回值作为另一个函数的参数。 4.函数的值传递:即传递给函数的变元只是一个局部变量,其在函数中的变动都不影响调用函数中的值。亦即函数会为传递来的变元生成一个局部拷贝。 5.从一个函数中返回值须使用关键字 return,return后的表达式的值作为返回值传递给调用函数。return主语句执行后,其后所有的语句都不再执行。一个函数中允许有多个return语句,但只能执行一个。 6.函数默认值的声明,如: int Function(int x=50); 因为参数名无实际意义,也可用  int Function(int =50); 对默认值的声明并不改变函数定义。但此种声明有一条限制,如果某个参数没有默认值,那该参数之前的所有参数均不可有默认值。 7.函数重载,各函数的参数要有区别,可以是参数类型、个数,或二者兼有。重载函数的返回值类型既可以相同,也可以不同。 8.内嵌函数,声明如: inline int Area(int); 每一次调用时都会将函数代码复制到调用函数中,适用于函数体较小时。可以节省内存开销,但多次调用会增加函数体。 9.函数递归分为直接递归和间接递归。直接递归是指函数直接调用其本身。间接递归是指指函数调用了另一个函数,而被调用函数则又调用了第一个函数。......

阅读全文(2532) | 评论:0

《常量》笔记(2006-10-09 21:55:00)

摘要:1.C++有两种常用常量:字面常量和符号常量。字面常量指直接写入程序语句的数值,如: int myAge=39; 2.符号常量是指用名字表示的常量,如同一个变量一样,不同的是在初始化之后其值不可以更改。C++有两种定义符号常量的方法: i.用 #define 来定义。该方法定义的变量无类型,在程序中只进行简单的文本替换,即把程序中的名字用相应的数字来替代。 ii.用 const 来定义常量。该方法可以定义变量的类型,这就使得编译器可以根据类型来正确的使用常量。 3.枚举型常量。可以使用它来创建一些新的类型,再定义这些新类型的变量。如: enum COLOR{WHITE,RED,BLUE,GREEN,BLACK}; COLOR myColor=BLUE; 每个枚举型常量都有一个整数值,若不特别指定,第一个常量值为0,其余依次增加。不过如果其中任何一个常量用一个特定的数值初始化,那么未被初始化的常量将在其前面已被初始化的常量的基础上增加。  ......

阅读全文(2252) | 评论:0

sizeof()操作符说明(2006-09-28 21:11:00)

摘要:sizeof()运算符返回括号中变量或数据类型的字节数。 如果括号中是一个变量,返回的是计算机为该变量保留的存储空间的字节数。 如果括号中是一个指针,无论该指针类型是什么,其返回值总为4。 如果括号中是一个数组名,则返回值是该数组的数据类型×数组长度。 如果括号中是一个数据类型名,则返回值是该数据类型在存储空间中占用的字节数。  ......

阅读全文(2520) | 评论:0

《变量与声明语句》笔记(2006-09-28 20:44:00)

摘要:1.变量名称遵循的原则 i.变量名称必须以字母或下划线开头,且只能含有字母、下划线和数字。不能含有任何其他空格、逗号或特殊符号。 ii.变量名称不能是关键字。 iii.变量名称不能由超过255个字符组成。 这些名称的选择同样适用于函数名称。 2.变量必须先声明后使用。具有相同类型的数据可以放在一条语句中声明。 3.声明语句说明: int a; int 告诉计算机要为一个整数保留足够的空间,a 则是告诉计算机要将保留的存储空间的第一个字节标记为名称“a”。 4.显示一个变量的地址,用地址运算符“&”。当该符号放在变量名前时,它代表的就是一个变量的地址。&price表示变量price的地址。 5.多数计算机中,short是2个字节,long是4个字节,而int可以是2个或4个字节(一般为4个字节),char是1个字节,float是4个字节,double是8个字节,bool是1个字节。 6.C++允许将定义与初始化混合使用。如:int a=5,b,c=6; 7.typedef(类型定义符)用来创建一个新名字,以取代冗长的类型定义符,如  typedef unsigned shor int USHORT; 8.当无符号整型变量的值达到其最大值时,该数值将回绕,如当一个int类型变量达到值65536时,其再加一后的值将变为0;有符号整型变量在达到最大值时也会回绕,但它是由最大的正值变为最小的负值(32767变为-32768)。  ......

阅读全文(2620) | 评论:0