C++#1

把C++回顾了,对一些细节总结下:
C++3个特性:抽象、继承、多态
虚函数:
  • 作用: 定义一个指向基类的指针,用一个派生类指针对其赋值,当调用派生类与基类一模一样的成员函数(参数、函数名)
    • 当基类中的此函数没有声明为virtual函数时,只能调用基类中的函数
    • 反之,如若基类中的此函数virtual ,则调用派生类中的函数
  • 实现:当基类中有任意虚函数时,在基类中维护一个虚函数函数表指针,即比原先的类声明多了四字节,当派生类中声明了相同的函数时,就用自己的函数地址代替原先的函数地址,通过引用或指针调用虚函数时,则到虚函数表中,取出相应的函数入口地址执行。
  • 典型应用: 当基类与派生类中都有动态申请内存空间的数据成员,当用一个派生类指针(引用)对一个基类的指针(引用)赋值时,对此指针执行delete操作,则只调用基类中的析构函数释放基类中动态申请的内存空间,造成派生类中的动态申请空间没有释放,导致内存泄露。如若,声明为virtual析构函数,则从派生类析构一直调用到基类的析构函数。(实现原理大致上也为将虚析构函数维护在一张表中,调用时,调用整张表的析构函数)。
Effective C++:
  • 使用const、inline 代替中的define(有些C++不支持)
  • 不要在构造函数与析构函数中调用虚数
  1. 原因:在派生类中的构造与析构函数中调用析构函数时,先构造基类,此时派生类成员还未初始化,C++不允许发生这种情况,所以调用基类中的虚函数。反过来,派生类先析构,其完成后,其数据成员没有被定义,所以基类中的只调用自己的虚函数
  2. 解决方法:在派生类的构造函数中,在初始化列表中对基类传送信息?
  • 在operator=等运算符重载中,返回*this指针(与一些STL实现一致)
  • 在copy构造与copy assignment中对自己和基类的所有成员赋值。在这两者中最好不要相互调用 (如果两者代码相同的很多,则再定义一个函数,供那两个调用)
  • 对于数据成员中有const、引用或者继承或包含的类没有默认构造函数,则必须自己写构造函数 。对于有指针成员和上述情况的,也必须自己写copy构造与copy assignment函数
关于函数参数与函数返回:
  • 给函数传递一个不是引用class对象,会调用一次拷贝构造函数
  • 函数返回一个局部class对象时,会调用拷贝构造函数
  • 对于运算符重载时,如加号重载,会产生一些隐形的转换:如下
  • class CComplex//类实现
    {
    private:
    	double dReal;
    	double dImaginary;
    public:
    	  CComplex(double Real = 4.0,double Imaginary = 3):
    	  dReal(Real),dImaginary(Imaginary)
    	  {
    			cout<<"In default CComplex."<<endl;			
    	  }
    	  CComplex operator+(CComplex obCComlex);
    	  CComplex(CComplex & obComplexTem)
    	  {
    			cout<<"In copy constructe"<<endl;
    			dReal = obComplexTem.dReal;
    			dImaginary = obComplexTem.dImaginary;
    	  }
    	  CComplex& operator=(CComplex &obCComlex);
    	  ~CComplex()
    	  {
    
    	  }
    	 void print(void)
    	  {
    		  cout<<dReal<<'+'<<dImaginary<<endl;
    	  }
    };

  • #include <iostream> 
    #include "Complex.h"
    
    using namespace std;
    
    
    int main(int argc,char*argv[])
    {
    	CComplex CC1;
    	CC1.print();
    	CComplex CC2(3,3);
    	CC2.print();
    	CC1 = CC2;
    
    	CComplex CC3;
    	CC3.print();
    	CC3 = CC1 + CC2;
    	
    	CComplex CC4;
    	
    	CC4 = CC1 + 4.0;
    	CC4.print();
    	return 0;
    }
    
    CComplex CComplex::operator+(CComplex obCComlex)
    {
    	CComplex obCC;
    	cout<<"In operator+"<<endl;
    	obCC.dReal = obCComlex.dReal + dReal;
    	obCC.dImaginary = obCComlex.dImaginary + dImaginary;
    
    	return obCC;
    }
    CComplex(double Real = 4.0,double Imaginary = 3):
    	  dReal(Real),dImaginary(Imaginary)
    	  {
    			cout<<"In default CComplex."<<endl;			
    	  }
    CC4 = CC1 + 4.0;
    代码,编译运行时正常的,因为class的有一个构造函数需要0或1或2double类型的参数,执行上面的代码时,会调用默认的构造函数(4,3)的临时对象。
  • 如果构造函数前加上explicit关键字(不能进行隐形的从double转成CComplex) 或则 加号的运算符重载需要一个CComplex引用类型参数,则编译不通过,提示no operator found which takes a right-hand operand of type 'double'
            评论
            添加红包

            请填写红包祝福语或标题

            红包个数最小为10个

            红包金额最低5元

            当前余额3.43前往充值 >
            需支付:10.00
            成就一亿技术人!
            领取后你会自动成为博主和红包主的粉丝 规则
            hope_wisdom
            发出的红包
            实付
            使用余额支付
            点击重新获取
            扫码支付
            钱包余额 0

            抵扣说明:

            1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
            2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

            余额充值