zoukankan      html  css  js  c++  java
  • C++ 基础知识(二)

    1.复制构造函数

    编译器会默认提供复制拷贝函数,但是也可以显式的定义,形参是本类对象的引用

    class point
    {
    private :
        int a;
        int b;
    public:
        point(int x,int y)
        {
            a=x;
            b=y;
            std::cout<<"调用构造函数"<<std::endl;
        }
        point(const point& p)      //显式的定义复制构造函数,必须是按引用传参&的形式,const可以不加,最好加
        {
            std::cout<<"调用复制构造函数"<<std::endl;
            a=p.a;
            b=p.b;
        }
        print()
        {
            std::cout<<a<<b<<std::endl;
        }
    };
    int main()
    {
        point p1(3,5);     
        point p2=p1;        //可以通过直接赋值的方式,这样会调用复制构造函数  
        p2.print();
        
        point p2(p1);      //也可以通过参数传参的方式,与上面的等价
        p2.print();
        return 0;
    }

    有些时候必须显式的定义复制构造函数,比如类中含有指针类的数据成员、需要使用动态内存,最好定义复制构造函数,避免内存错误

    2.友元
    友元函数:

    下面的例子通过友元函数来访问类内部私有成员,该友元函数不属于任何一个类

    class point
    {
    private :
        int a;
        int b;
    public:
        point():a(3),b(4)
        {
    
        }
        show_ab();
        friend void show_ab_f(point &p);   //声明友元函数
        int c=5;
    };
    
    point::show_ab()
    {
       std::cout<<a<<b<<std::endl;          //成员函数访问私有对象
    }
    
    void show_ab_f(point &p)                //定义友元函数,此函数不属于任何类
    {
       std::cout<<p.a<<p.b<<std::endl;      //友元函数访问私有对象
    }
    
    int main()
    {
        point p;
        p.show_ab();                         //调用成员函数 
        show_ab_f(p);                        //调用友元函数,传入point类
        std::cout<<p.a<<p.b<<std::endl;      //报错,私有对象只能类成员访问
        std::cout<<p1.c<<std::endl;          //只能访问共有对象
        return 0;
    }
    

    上面的例子是一个全局函数为point的友元函数,也可以定义一个类的成员函数为另一个类(point)的友元函数

    那么该函数既可以访问本类的成员,也可以访问类point的成员,这里就不写例子了

    友元类:

    友元类,就是一个类(line)是另一个类(point)的友元类,那么友元类(line)的所有成员函数都可以访问point类的所有成员,如下例:

    class  line;   //先声明line类,后面在定义,不然下面point类中不认识line
    class point
    {
    private :
        int a;
        int b;
        friend line;    //声明友元类
    public:
        point():a(3),b(4)
        {
        }
    };
    class line  //定义line类
    {
    public:
        show(point& p)
        {
            std::cout<<p.a<<p.b<<std::endl;  //访问point的成员
        }
    };
    int main()
    {
        point p;
        line _line;
        _line.show(p);
        return 0;
    }

    3.内联函数(inline)

    内联函数就是在函数定义前加上inline关键字的函数。
    例如A函数调B函数,B函数是内联函数,则编译器会把B函数的函数体复制到A函数里面,A函数里包含了B函数的代码,而B函数则不存在了,从而节省反复调用的函数开销

    为什么要用inline?

    假设有下列min()函数

    int min( int v1, int v2 )  
    {  
        return( v1 < v2 << v1 : v2 );  
    }

     为这样的小操作定义一个函数的好处是:

    • 如果一段代码包含min()的调用,那阅读这样的代码并解释其含义比读一个条件操作符的实例,可读性会强很多。
    • 改变一个局部化的实现比更改一个应用中的300个出现要容易得多
    • 语义是统一的,每个测试都能保证相同的方式实现
    • 函数可以被重用,不必为其他的应用重写代码 

    不过,将min()写成函数有一个严重的缺点:如果程序中有很多地方频繁的调用min函数,这样的话,比直接计算条件操作符要慢很多。为什么?

    假设A函数中调用了B函数,在调用B函数时,先要中断A函数,将执行流程转移到B函数中,等B函数执行完,再返回A函数,所以在调用B函数前,要保护A函数的现场,记录程序当前位置,以方便从B函数返回,恢复现场,并从原来的位置继续执行. 如果频繁调用,则会影响程序性能
    inline 函数正是为了解决这个问题的。总结下:
    (1)inline函数就是以空间换时间,是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率
    (2)inline函数必须在函数定义前加 inline关键字,声明前加则不起作用
    (3)对于像一些短小,调用频繁的函数可以使用inline。对一些很长的函数,或者包含循环,switch,递归的函数不要使用inline。
    (4)inline对于编译器来说只是一个建议,编译器可以选择忽略该建议。换句话说,哪怕真的写成了inline, 而且没有错误,编译器也会自动进行优化。所以当inline中出现了递归,循环,或过多代码时,编译器自动无视inline声明,同样作为普通函数调用

    4.函数的重载
    一个函数有相同的名字,但是传参的形式和返回值不一样,则视为函数的重载
    不能出现名字相同,传参相同,仅仅是返回值不同的重载,编译器会报错。
     

    5.继承
    (1).基类和派生类:B类继承自 A类,则A类称为基类,B类称为派生类
    (2)直接基类和间接基类。 举例孙子继承父亲,父亲继承爷爷。父亲是孙子的基类,也称为直接基类,爷爷是父亲的直接基类。而爷爷是孙子的间接基类。
    (3)public继承,protect继承,private继承
    public、protected、private方式继承后,成员属性的变化如下表:

    (4)多基派生和单基派生
    单基派生就是指 派生类只有一个基类。
    多基派生就是指 派生类有多个基类,既同时继承多个基类,C++ 支持多继承


     

  • 相关阅读:
    MyISAM和InnoDB的区别
    MySQL——索引与优化
    jquery选择器及效率问题
    Mac 可设置环境变量的位置、查看和添加PATH环境变量
    javascript默认中文(汉字/标点)长度均为1的解决
    苹果下抓屏截屏方法 包括全屏、选择区域、窗口抓屏等
    java实现window phone推送通知
    设计模式总结
    NHibernate 帮助类(单例实际运用)
    访问者模式
  • 原文地址:https://www.cnblogs.com/kevinWu7/p/10163444.html
Copyright © 2011-2022 走看看