一、 指针(*)与引用(&)的异同:
指针与引用都是表示一个变量的地址,但是它们的使用方式有很大的区别:
1、 引用在声明的时候必须使用一个变量进行初始化,而且以后引用指向的地址永远不能够改变,引用所有的操作都作用于初始化变量,
2、 但是指针没有这些限制。
3、 使用的方式有很大的区别:
int a=10;
int& cite=a;
int* pointer=&a;
cite++;
(*pointer)++;
Cite.method();
Pointer->method();
二、 指针数组:
cout << pointer+1 << endl; // 23456789
cout << pointer << endl; //123456789
cout << *pointer << endl; //1
cout << *(pointer+1) << endl; //2
cout << *pointer+1 << endl ; // error;
三、 const
1、 const dataType data=dataValue; //以后data的值不允许变化。
但是实际上可以通过非法的手段修改const的值的,例如:
void TestConst()
{
int const num=10;
int& cite=(int&)num;
int* pointer=(int*)#
cout << "no change--------:"<<endl
<<"num=" << num << endl //10
<<"cite=" << cite << endl //10
<<"*pointer="<<*pointer << endl; //10
cite++;
cout << "cite++--------:"<<endl
<<"num=" << num << endl //10
<<"cite=" << cite << endl //11
<<"*pointer="<<*pointer << endl; //11
(*pointer)++;
cout << "(*pointer)++--------:"<<endl
<<"num=" << num << endl //10
<<"cite=" << cite << endl //12
<<"*pointer="<<*pointer << endl; //12
}
所以类中函数不应该返回指向自己私有变量的引用或者指针,尽管这些变量使用const限制。
2、 指针与const的组合:
a、datatype * const pointer; :对指针作限制,指针的内容(也即变量的地址)不能够改变,但是指针对应变量的内容可以改变
b、Const datatype * pointer; :对指针对应变量的内容进行限制,也即指针不能够改变变量的值,但是指针可以改变它指向的位置。
c、Const datatype * const pointer; :指针保存的变量的位置以及对应变量的内容都作限制,都不允许改变。
可以这样记忆:
线型考虑,const仅仅对自己后面的名词起作用:
如a情况的话,const 对pointer 起限制作用,也就是pointer的内容不允许改变,而pointer的内容为变量的内存地址,也就是不允许指针指向的变量进行改变。
如b情况的话,const 对* pointer起限制作用,而*pointer表示指针指向变量的内容,也就是指针指向变量的内容不允许改变,但是pointer的内容却可以改变,也就是pointer可以改变指向的变量。
c情况则对上面两种都作限制。
3、 尽量多使用const而不是用#define parameter=value这种方式,因为后者依赖于c 预编译程序,不利于错误的查找。
四、 Inline函数:
inline函数也是依赖于c预编译程序的,任何使用inline函数的地方,都会使用inline的代码直接替换
优点有:可以减少函数间的调用,而且预编译程序对不同使用情况会有专门的优化措施,所以运行速度快。
但是缺点也对应的存在:a、增加编译后文件的大小,增加在运行时内存需求量。
B、如果inline函数过于复杂,预编译程序就把把它作为普通的函数进行是用,而且具体的处理方式依赖于c编译器,并不是所有的编译器都一样的对待,所以有出现错误的可能。
五、 友元成员(外部类、外部类方法、外部函数):
1、 所谓的友元成员是指在一个类中进行声明的,具有特权访问该类的private以及protected parameter的成员。
2、 友元成员并不是声明类的一部分。
3、 子类不具有友元成员声明的继承性。
六、 *.h、*.c、*.cpp文件各自作用:
1、 *.h文件一般用来作为公共引用(#include)、函数、类以及公共变量或者类型的声明的地方,而*.c、*.cpp一般用来作为函数以及类实现的地方。
2、 如果想使用非本“域”的类、函数的话,一般会在文件头使用#include “name.h”声明,将这些类引入本“域”,是这些类或者函数在本“域”可感知。
3、 对于函数或者公共变量也可以使用“extern”进行生命,使它们在本“域”可以被感知。
七、 有关类继承的一些知识小结:
1、 类名::成员名称,在这里“::“起作一个作用域限制作用
2、 在子类中明确的调用父类的每个方法: ClassBaseName::Method(…..)。
3、 如果一个子类继承了多个父类,而这些父类有相同名称的函数,而子类却没有重载它们的话,要使用子类调用这些函数,则必须明确的指明父类的名称,即:son.ParentClassName::Method();
4、 虚函数(用virtual声明的函数):即可以被子类重载的函数。
5、 纯虚函数是指在父类中使用virtual标示而没有实现的函数,子类必须实现这个函数才能够使用,纯虚函数声明方式: virtual returnType MethodName(…..)=0;
6、 Abstract类,即其中至少含有一个纯虚函数声明的类,这种类不能够直接使用,只能够通过子类实现这些纯虚函数。
7、 C++中virtual derivation 与Nonvirtual Derivation的区别:
8、 在c++中的Novirtual Derivation 等同于c#中new关键字重载父类函数,而virtual derivation等同于c#中的override关键字重载父类函数。
9、 public、protected、private继承。
public继承为”类型继承“,基类的所有公共成员都成为基类的public成员,它可以改写基类的实现方式,继承基类的公共接口,反映了"is-a"的关系。
private继承为”实现继承“,基类的所有公共成员都成为派生类的私有成员,派生类不直接支持基类的公共接口,但它可以实现自己的公共接口,并且重用基类的功能实现。
protected继承是指基类的所有公共成员都成为派生类的protected成员,它可以使用基类的功能实现,但是对外不能够继承基类的公共接口,并且可以被”后来从该类继承的派生类“访问。
private继承与组合的选择
10、 构造函数与析构函数的顺序。
八、 RIIT(运行时刻类型辨别):
1、 dynamic_cast:安全的转换函数,一般在转换前执行两部操作:操作之前进行检验所执行的转换是否有效,只有在有效的情况下才执行转换。
一般用作基类指针向派生类指针转换,如果转换无效则返回0。
也可以用作基类引用向派生类 引用转换,但是如果转换失败会引发异常(std::bad_cast)。
2、 typeid(表达式或者ID):动态的获取一个表达式或者ID的类型信息,返回type_info类变量。
3、 type_info类:来表示类型信息的类,具有name(),raw_name(),==,!=等成员,常常和typeid用来判别对象的类型信息,使用方法如下所示:
cout << typeid(student*).name() << endl; //student*
cout << typeid(student).name() << endl; //student
cout << typeid(student&).name() << endl ; //student
if(typeid(oneStudent)==typeid(student)) .....;
九、 异常处理:
try
{
....
throw exception(...);
}
catch(exception ex)
{
...
}
1、 处理所有的异常:
catch(...)
{
.....
throw; //重新抛出异常。
}
2、 异常与虚拟函数:
一般常用catch(Exception& ex)来避免这种情况。
情况类似于下面的情况:
ChildClass child;
BaseClass base=child;
base.VirtualMethod();
//这个时候还是使用的是BaseClass的实现,而不是ChildClass的实现。
-------------------------------
ChildClass child;
BaseClass& base=child;
base.VirtualMehod();
//这个时候使用实际上是ChildClass的实现,而不是BaseClass的实现。
也说明了要调用派生类的虚拟函数则对应基类必须生命为指针或者引用。
3、 在函数或者函数指针后面添加 throw(exceptionType)表明该函数或者函数指针可能会抛出的一场类型。
十、 重载操作符:
1、 声明方式:
bool operator ==(const MyClass& myClassObject);
bool operator ==(const MyClass& object1,const MyClass& object2);
2、 重载操作符分为内置(类成员)与外置(非类成员)两种,如果非类成员重载操作符好使用类的保护或者私有成员的话则需要声明为类的友成员。
3、 只有C++中预定义的操作符号才能够重载,类设计者不能够声明一个非C++预定义的操作符进行重载。
4、 预定义操作符的优先级不能够被改变,操作符的参数个数不能够被改变。
5、 内置操作符如果有多个参数,那么当前类对象被默认(必须被默认)为第一个参数,但是不需要显示的放置在操作符的参数列表中,而外置操作符则必须将所有的参数明确的列示出来。
6、 付值(=)、下标([])、调用(())和成员访问箭头(->)必须被定义类成员操作符。
结构体、宏、函数指针、模版、STL、数据结构、Socket、ACE、ICE。