针对这个示例代码总结了以下几个问题(当做对以往知识的回顾): 第一、关于静态成员变量,static int a; 这样的静态成员变量,如果在任何地方(无论是类内还是类外)都不使用,可以不去声明这个静态变量(静态变量的声明在类外面),如果使用这个静态变量,不管是在任何位置使用,都要在类外进行声明或初始化!原因是,这个静态变量定义在类中,由于它是静态属性的(即全局属性),所以可以使用在类外面。当然使用前就要去声明了!同理 static const int a = 10;这样的静态成员常量,在类中定义的过程中,就应该完成初始化赋值,因为它是一个常量!同样它不需要在类外面进行声明就可以使用,原因就是,它是一个static属性的全局常量,全局常量的使用,还需要声明吗!只要注意下,命名空间就好了! 第二、静态成员函数中是不可以使用,普通成员变量的,因为普通成员变量,是在类中直接调用,在类外通过对象进行调用的!而静态成员函数,没有定义在类内,它是static属性的!只是定义在全局区中的某个特定的命名空间中的! 第三、类中的变量,都是不能直接在类中定义变量的时候进行赋值的!!!能够直接赋值的都是常量,枚举常量,static const int a = 10; 静态成员常量,还有就是通过构造函数初始化列表赋值的const int a;普通成员常量! 第四、对于构造函数的初始化列表的赋值,不仅仅可以给常量赋值,也可以给成员变量赋值! b.使用虚函数进行多态类型识别的缺点: 第一、必须从基类开始提供类型虚函数 第二、所以派生类都必须重写类型虚函数 第三、每个派生类的类型ID必须唯一,当派生类增多的时候,很难保证ID唯一 利用虚函数进行多态类型识别的方法可以满足工程的需要,但是维护性会随着派生类的增多而成指数级增长!!!
4.动态类型识别(dynamic_cast的方式):
a. dynamic_cast关键字,主要是用于基类和派生类之间的强制类型转换用的,但是前提是类族中至少有一个虚函数(即父类中必须有一个虚函数,因为这样子类中也同样继承了父类的这个函数,就构成了类族中的一个多态)。当用于指针转换时,转换失败返回空指针,当用于引用转换时,转换失败将引发bad_cast异常! b. 这里说下dynamic_cast与static_cast的区别:当对于基类和派生类之间不管是对象还是指针进行强制类型转换的时候,static_cast都可以将其转换,这个转换的过程就跟使用c语言强制类型转换的过程是一样的,是野蛮的,是不计后果的,是在编译期间进行的。但是dynamic_cast只能转换具有继承关系对象的指针和引用,且它是在程序运行的过程中,进行转换的,是动态的,是安全的,需要去判断结果的(有成功有失败很安全)。static_cast则直接就是转换了,不分情况。但是dynamic_cast需要有虚函数,而且对于没有继承关系且有虚函数的对象的指针也可以进行转换,虽然没有意义! 示例代码:#includec.dynamic_cast的优势:不用显示的声明和定义类型虚函数,不用为类族中的每一个类型分配类型ID dynamic_cast的缺陷:只能用于具有虚函数的类族 注意:使用dynamic_cast进行动态类型识别可以取代类型虚函数的方案,但是在本质上dynamic_cast还是需要类族中存在虚函数的(在工程中常把析构函数作为这个虚函数定义)using namespace std; class parent { public: virtual ~parent() { } }; class child : public parent { public: int add(int a, int b) { return a + b; } }; void test(parent* p) { child* c = dynamic_cast (p); if(NULL != c) { cout << c->add(2,7) << endl; } else { cout << "error!" << endl; } } int main() { parent p1; child c1; test(&p1); test(&c1); return 0; }
5.typeid关键字:
a. c++提供了typeid关键字用于动态获取类型信息,typeid关键字返回对应参数的类型信息,typeid返回一个type_info类对象,type_info类的使用需要包含
#include注意:第一、typeid关键字 需要#include //使用typeid关键字的时候 需要这个头文件 using namespace std; class parent { }; int main() { parent p; int a; char* c; const type_info& tip = typeid(p); //当使用type_info创建对象的时候,一定是常引用 const type_info& tip1 = typeid(parent); //因为typeid是关键字 不是函数,所以后面可以是类型 const type_info& tii = typeid(a); const type_info& tic = typeid(c); cout << tip.name() << endl; cout << tip1.name() << endl; cout << tii.name() << endl; cout << tic.name() << endl; /*一般不去判断tip.name()这个字符串,都是用==重载函数进行判断*/ cout << (typeid(p) == typeid(parent)) << endl; cout << (typeid(a) == typeid(int)) << endl; cout << (typeid(c) == typeid(char*)) << endl; cout << (typeid(*c) == typeid(char)) << endl; return 0; }
示例代码:
#include注意:最后这个程序有两个疑问~~~~ 第一、就是父类中一定还是需要有一个虚函数,如果类族中没有这个虚函数,typeid(*p)会一直跟typeid(parent)相等。根本就不会等于typeid(child),可以去掉上面程序中父类的虚函数试试!!! 第二、为什么typeid(*p)能与typeid(child)相等,而typei#include using namespace std; class parent { public: virtual ~parent() { } }; class child : public parent { public: int add(int a, int b) { return a + b; } }; void test(parent* p) { if(typeid(*p) == typeid(child)) { child* c = (child*)p; cout << c->add(2,7) << endl; } else { cout << "error!" << endl; } } int main() { parent p1; child c1; test(&p1); test(&c1); return 0; }