C++复习-01

C++复习-01 (想到哪写到哪系列)
  1. C++析构函数为什么要写成virtual

    class Base
    {
    public:
        Base(){cout << "Base" << endl;}
        ~Base(){cout << "~Base" << endl;}
        //void print(){cout << "This is Base" << endl;}
    };
    
    class Device : public Base
    {
    public:
    	Device(){cout << "Device" << endl;}
    	~Device(){cout << "~Device" << endl;}
    };
    
    //main fun call
    Base * p = new Device;
    delete p;
    
    //output
    Base
    Device
    ~Base
    

    看上面的案例,子类的析构函数没有被调用,在子类中析构函数要被释放的资源将不能被正确的释放。(为什么会这样?C++多态的实现原理中具体说)

  2. 某个函数在基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不需要再显式地声明为virtual,测试案例如下:

    class Base
    {
    public:
        Base(){cout << "Base" << endl;}
        virtual ~Base(){cout << "~Base" << endl;}
        virtual void print(){cout << "This is Base" << endl;}
    };
    
    class Device : public Base
    {
    public:
    	Device(){cout << "Device" << endl;}
    	~Device(){cout << "~Device" << endl;}
    	void print(){cout << "This is Device" << endl;}
    };
    
    class Device1 : public Device
    {
    public:
    	Device1(){cout << "Device1" << endl;}
    	~Device1(){cout << "~Device1" << endl;}
    	void print(){cout << "This is Device1" << endl;}
    };
    
    //main fun call
    Base * p = new Device1;
    p->print();
    delete p;
    
    //output
    Base
    Device
    Device1
    This is Device1
    ~Device1
    ~Device
    ~Base
    

    很显然,在Device类中没有使用virtual关键字,但是在Device1的 print()和析构函数都正确调用

  3. 函数返回值如果是引用类型,一定不要返回局部变量

    //错误示例
    int & print()
    {
    	int aaa = 7;
    	return aaa;
    }
    

    Primer Plus:"由于aaa对象是局部变量,在函数结束时将被删除,因此引用将指向 一个不存在的对象。 "

    问:这么基础为什么写出来呢?

    答:我之前一直认为,当返回引用后,只要返回的引用被接收,那么代表aaa对象还在被使用,不会被干掉,其实在大括号结束的时候它的生命周期已经over

  4. 运算符重载

    对于非成员重载运算符函数来说,运算符表达式左边的操作数对应于运算符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。

    对于成员成员重载运算符函数来说,运算符表达式左面的操作数对应调用对象(类的一个对象),运算符右边的对象是作为参数被传递的对象。

    class Base
    {
        double m_v;
    public:
        Base(double v){m_v = v;}
        void print(){cout << m_v << endl;}
        Base operator *(double tt) const
        {
            double temp = (this->m_v) * (tt);
            return Base(temp);
        }
    };
    
    //in main func
    Base te = 23.7 * d;	//error ①
    Base te = d * 23.7; //right ②
    

    对于上面定义了*重载的类中,操作符的左面只能是类对象。要想第一种调用成功,有两种方法,如下:

    *** 注意:两种方法不能同时存在

    //方法一:在类的外面定义如下函数
    Base operator *(double m, const Base &b)
    {
        return b * m;
    }
    //方法二:使用友元函数
    friend Base operator *(double m, const Base &b); //在类中添加
    Base operator *(double m, const Base &b)	//类的外面定义
    {
        return Base(b.m_v * m);
    }
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值