one/181.C中调用C++代码1)对于C++中非类的成员函数,可以简单的在函数声明前面加extern“C”,通常函数声明位于头文件中,当然也可以将声明和函数定义一起放在cpp中,在没有声明的情况下,直接在定义前添加extern“C”也可//C++code:externCvoidf(int。voidf(inti{//...}然后,你可以这样使用f(:/*Ccode:*/voidf(int。voidcc(inti{f(i。/*...*/}2)对于C++类的成员函数,则需要另外做一个cpp文件,将需要调用的函数进行包装。//C++code:classC{//...virtualdoublef(int。}。externCdoublecall_C_f(structC*p,inti//wrapperfunction,incppfileb5E2RGbCAP{returnp-f(i。}然后,你就可以这样调用C::f(:/*Ccode:*/doublecall_C_f(structC*p,inti。//再声明下voidccc(structC*p,inti{doubled=call_C_f(p,i。//函数中调用C++代码/*...*/}如果你想在C里调用重载函数,则必须提供不同名字的包装,这样才能被C代码调用。例如://C++code:voidf(int。voidf(double。externCvoidf_i(inti{f(i。}externCvoidf_d(doubled{f(d。}two/18然后,你可以这样使用每个重载的f(:/*Ccode:*/voidf_i(int。voidf_d(double。voidcccc(inti,doubled{f_i(i。f_d(d。/*...*/}2C++中调用C代码对于C中的函数代码,要么将C代码的头文件进行修改,在其被含入C++代码时在声明中加入extern“C”或者在C++代码中重新声明一下C函数,重新声明时添加上extern“C”头。p1EanqFDPw加extern“C”头一定是加在C++的代码文件中才能起作用的。1)在sourceFile文件目录下建bb.c文件,代码:2)在CCallCpp.cpp中添加代码:3)在headFile中加入#includestdio.h//标准输入输出文件分析一下这个现象的实质原因:three/18C编译器编译函数时不带函数的类型信息,只包含函数符号名字,如C编译器把函数inta(floatx编译成类似_a这样的符号,C连接器只要找到了调用函数的符号,就可以连接成功,它假设参数类型信息是正确的,这是C编译连接器的缺点。而C++编译器为了实现函数重载,编译时会带上函数的类型信息,如他把上面的a函数可能编译成_a_float这样的符号为了实现重载,注意它还是没有带返回值得信息,这也是为什么C++不支持采用函数返回值来区别函数重载的原因之一,当然,函数的使用者对函数返回值的处理方式如忽略)也是重要原因。DXDiTa9E3d基于以上,C调用C++,首先需要用封装函数把对C++的类等的调用封装成C函数以便C调用,于是externC的作用是:让编译器知道这件事,然后以C语言的方式编译和连接封装函数通常是把封装函数用C++编译器按C++方式编译,用了externC后,编译器便依C的方式编译封装接口,当然接口函数里面的C++语法还是按C++方式编译;对于C语言部分--调用者,还是按C语言编译;分别对C++接口部分和C部分编译后,再连接就可以实现C调用C++了)。相反,C++调用C函数,externC的作用是:让C++连接器找调用函数的符号时采用C的方式,即使用_a而不是_a_float来找调用函数。externC是连接申明(linkagedeclaration,被externC修饰的变量和函数是按照C语言方式编译和连接的RTCrpUDGiT注:如果你用VC6.0编译附件时遇到类似:“fatalerrorC1010:unexpectedendoffilewhilelookingforprecompiledheaderdirective”报错的话,请将bb.c文件做如下处理右键点击工程工程中的该文件,选择setting,在c/c++栏,选择PreCompiledheaders,然后设置第一选项,选择不使用预编译头。5PCzVD7HxA3register声明的变量为寄存器变量,直接存放在机器的寄存器中。1)在C++中,只有局部变量和形参可以定义为寄存器变量,全局变量、局部静态变量不可以。一旦使用了&符,被定义的变量会强制放在内存中。jLBHrnAILg2)在C中,register关键字可以定义全局变量,但不建议用&符;在定义局部变量时,不能用&符。5赋值兼容性:在任何需要基类对象的时候都可以用公有派生类的对象代替,这就是赋值兼容性规则。派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的成员赋值给基类对象。反过来不行,因为派生类的新成员无值可赋。xHAQX74J0X可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,不能访问派生类中的新成员。同样也不能反过来做。LDAYtRyKfE派生类对象可以初始化基类的引用。引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。6数据成员不能用自动(auto、寄存器(register或外部(extern类型定义7对象的赋值(1)两类型须相同,赋值兼容性规则除外(2)经行赋值时,两对象的对应成员逐一复制)赋值,两个对象仍然是彼此独立的,各自有自己的内存空间。four/18(3)如果类中存在指针,则不能简单的经行赋值,否则会产生错误8在头文件中,用“”标示的,编译器首先在源文件下所在目录下寻找头文件,没有再在库文件中找,用则相反。Include与include的区别。Zzz6ZB2Ltk9class和struct的区别:1)在C,C是一种过程化的编程语言,struct只能定义成员变量,不能定义成员函数structPoint{intx。//合法inty。//合法voidprint(//不能定义成员函数{printf(Pointprint\n。//编译错误}}。dvzfvkwMI1提示如下编译错我:“函数不能作为point”结构体的成员2)在C++中,struct有成员函数和构造函数,还有class的其他属性,如继承、虚函数等,C++中struct扩充了C的struct功能,但区别在:rqyn14ZNXIC++中的struct和class的区别:对于成员访问权限以及继承方式,class中默认的是private的,而struct中则是public的。class还可以用于表示模板类型,struct则不行。EmxvxOtOco答案:C的struct与C++的class的区别:struct只是作为一种复杂数据类型定义,不能用于面向对象编程。C++中的struct和class的区别:对于成员访问权限以及继承方式,class中默认的是private的,而struct中则是public的。class还可以用于表示模板类型,struct则不行。SixE2yXPq5C++中保留struct关键字只是为了C++编译器能兼容C程序。10构造函数的名字必须与类名相同,因为:这样系统不会把它当做一般的函数处理对象数组会和new创建的对象数组都会调用构造函数,创建几个对象就会调用几次析构函数但new需delete才会调用析构函数)Pointp[3]。6ewMyirQFL11new与delete:使用delete运算符释放它时,delete会自动调用析构函数。在程序中,如果不显式的撤销对象,系统不会自动调用析构函数。也就是说new运算符动态创建的对象,如果不用delete运算符释放它,系统不会自动调用析构函数。kavU42VRUs12new不能对动态分配的数组进行初始化如int*p。p=newint[10](0//错误13三中传递方式比价1)使用对象作为函数参数:形参需占存储空间,形参和实参的结合是值传递,实参将自己的值传递给形参,形参实际上是是实参的副本,是一种单向的传递,形参的变化不会影响到实参y6v3ALoS892)使用指针作为作为参数传递,形参需占存储空间,形参和实参的结合是地址传递,实参将自己的地址传递给形参,是一种双向传递,形参的变化直接影响到实参。缺点是阅读性差M2ub6vSTnP3)使用引用作为函数参数:并没产生实参的副本,直接对实参操作,双向传递,形参的变化直接影响实参,易使用当参数传递的数据较大时,用引用比一般的变量传递的效率和所占的空间都好。0YujCfmUCwfive/18声明引用的格式:数据类型&引用名=已定义的变量名)141)非成员函数作为类的友元函数:在类的定义中使用关键字friend进行声明friend返回值类型函数名(形参表此时,友元函数在类外定义时,不能在函数前加”类名::“,因为它不是该类的成员函数,友元函数没有this指针eUts8ZQVRd2)成员函数作为友元函数:classA{classB{//……//……voidfa(。friendvoidA::fa(。}}成员函数fa声明为类B的友元函数,就有访问类B保护成员和私有成员的特权3)友元类:classA{classB{//……//……voidfa(。friendA。}}类A声明为类B的友元类,则类A的每个成员函数都有访问类B的保护或私有成员15组合、继承、多态1)派生类具有基类的所有属性和行为。且可以增加新的行为和属性2)公有继承1)基类的private、protected、private成员的访问属性在派生类中保持不变2)派生类中继承的成员函数可以直接访问基类的所有成员,派生类中新增的成员函数只能访问基类的public和protected成员,不能访问基类的private成员sQsAEJkW5T3)派生类对象只能访问基类的public成员3)受保护继承1)基类的public、protected成员都以protected身份出现在派生类中2)派生类中新增的成员函数可以直接访问基类的public和protected成员,但不能访问基类的private成员GMsIasNXkA3)派生类的对象不能访问基类的任何成员3)私有继承1)基类的public和protected成员都以private身份出现在派生类中2)派生类中新增的成员函数可以直接访问基类的public和protected成员,但不能访问基类的private成员TIrRGchYzg3)派生类的对象不能访问基类的任何成员4)派生类不能继承基类的构造函数和析构函数,派生类对基类有参数的构造函数及派生类的数据成员必须经行初始化。当派生类也做基类时,则各派生类只负责其直接基类的构造7EqZcWLZNX4)继承与组合中构造和析构的顺序:1)调用基类的构造函数2)根据类中声明的顺序构造组合对象3)派生类中构造函数的执行析构则正好相反注意:1)派生类不能继承基类的构造函数和析构函数。当基类有带参数的构造函数six/18时,派生类必须定义构造函数,以便把参数传递给基类的构造函数lzq7IGf02E2)当派生类也做为基类使用时,各派生类只负责直接基类的构造。3)因为析构函数不带参数,派生类和基类对析构函数的存在互不依赖。5)多态:1)封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!zvpgeqJ1hk2)一个接口,多种方法。在程序运行过程中调用的函数3)开门、开窗户、开电视。在这里的开就是多态!6)静态绑定和动态绑定1)静态绑定在编译阶段完成,包括成员函数重载和派生类对基类函数的重载2动态绑定在运行时把发送对象的消息