zoukankan      html  css  js  c++  java
  • C++学习笔记第三天:类、虚函数、双冒号

    class Box
    {
       public:
          double length;   // 盒子的长度
          double breadth;  // 盒子的宽度
          double height;   // 盒子的高度
    };

    类成员的作用域:

    public:公共成员。访问权限:外部、子类、本身

    protected:受保护成员。访问权限:子类、本身

    private:私有成员。访问权限:本身

    构造函数

    跟其他语言一样,使用类名作为函数名,无返回值,可以有参数。

    #include <iostream>
     
    using namespace std;
     
    class Line
    {
       public:
          void setLength( double len );
          double getLength( void );
          Line();  // 这是构造函数
     
       private:
          double length;
    };
     
    // 成员函数定义,包括构造函数
    Line::Line(void)
    {
        cout << "Object is being created" << endl;
    }
     
    void Line::setLength( double len )
    {
        length = len;
    }
     
    double Line::getLength( void )
    {
        return length;
    }
    // 程序的主函数
    int main( )
    {
       Line line;
     
       // 设置长度
       line.setLength(6.0); 
       cout << "Length of line : " << line.getLength() <<endl;
     
       return 0;
    }

    如果是带参数的构造函数,可以使用初始化列表:

    Line::Line( double len): length(len)
    {
        cout << "Object is being created, length = " << len << endl;
    }

    上面的语法等同于如下语法:

    Line::Line( double len)
    {
        cout << "Object is being created, length = " << len << endl;
        length = len;
    }

    如果有多个参数,中间用逗号隔开:

    Line::Line( double len): length(len), para02(var02)
    {
        cout << "Object is being created, length = " << len << endl;
    }

    另外,初始化列表并不是构造函数专用的,类的普通成员函数也可以使用。

    析构函数

    这个挺新鲜的,作用跟构造函数正好相反,在对象被销毁的时候执行。

    无返回值,无参数,所以无法重载,一个类只能有一个析构函数

    函数名也是与类同名,只需要在前面加一个波浪线前桌:~

    在析构函数中,主要用来销毁在构造函数或成员方法里 new 出来的对象或指针,最常用的就是:delete obj

    #include <stdio.h>  
    #include <iostream>  
    #include <vector>  
    using namespace std;  
    
    struct CP  
    {  
        int a;  
        int b;  
    };  
    
    class TEST  
    {  
        public:  
            CP* compound;  
            int num;  
        TEST(){  
            compound = new CP();  
            cout << "create a new TEST obj" << endl;  
        };  
        ~TEST(){  
            cout << "delete TEST obj" << endl;  
            delete compound;  
        };  
    };  

    类的继承

    跟JAVA不同,C++中允许一个类继承多个父类:

    #include <iostream>
     
    using namespace std;
     
    // 基类 Shape
    class Shape 
    {
       public:
          void setWidth(int w)
          {
             width = w;
          }
          void setHeight(int h)
          {
             height = h;
          }
       protected:
          int width;
          int height;
    };
     
    // 基类 PaintCost
    class PaintCost 
    {
       public:
          int getCost(int area)
          {
             return area * 70;
          }
    };
     
    // 派生类
    class Rectangle: public Shape, public PaintCost
    {
       public:
          int getArea()
          { 
             return (width * height); 
          }
    };
     
    int main(void)
    {
       Rectangle Rect;
       int area;
     
       Rect.setWidth(5);
       Rect.setHeight(7);
     
       area = Rect.getArea();
       
       // 输出对象的面积
       cout << "Total area: " << Rect.getArea() << endl;
     
       // 输出总花费
       cout << "Total paint cost: $" << Rect.getCost(area) << endl;
     
       return 0;
    }

    输出:

    Total area: 35
    Total paint cost: $2450

    虚函数

    这个不太好理解,只能按照别人的描述硬性记忆:在类的成员函数前面加 virtual 表示该成员函数为虚函数。

    虚函数在C++中的作用不低,很多官方的源码中都存在大量的虚函数

    目前位置能理解的作用包括:

    1、允许用基类的指针来调用子类的这个函数:

    class A  
    {  
        public:  
            virtual void foo()  
            {  
                cout<<"A::foo() is called"<<endl;  
            }  
    };  
    class B : public A  
    {  
        public:  
            void foo()  
            {  
                cout<<"B::foo() is called"<<endl;  
            }  
    };  
    int main(void)  
    {  
        A *a = new B();  
        a->foo();   // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的!  
        return 0;  
    }

    2、通过“纯虚函数”实现抽象类

    虚函数:

    virtual ReturnType funtion1(params...);

    虚函数在基类中可以有默认实现,派生类也可以覆盖;

    但如果在基类中没有默认实现,那么派生类必须具体实现。

    纯虚函数:

    virtual ReturnType funtion1(params...)=0; 

    在虚函数声明的后面加“=0”就表示这是一个纯虚函数,含有纯虚函数的类成为抽象类。

    纯虚函数用来规范派生类的行为,即接口。派生类中必须对这个纯虚函数进行具体实现。

    抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。

    对虚函数的理解,有一个很好的比方:

    比如你有个游戏,里面有个含有纯虚函数 [攻击] 的抽象类 [怪物],然后有三个派生子类 [狼][蜘蛛][蛇] 都继承了 [怪物],并且都各自实现了自己独特的 [攻击] 函数。

    那在出现怪物的时候就可以定义一个 虚基类指针数组,把各种怪物的指针给它,然后迭代循环的时候直接:怪物[i]->攻击() 攻击玩家就行了

    Monster *pMonster[3];
    pMonster[0] = new Wolf(); //初始化一匹狼
    pMonster[1] = new Spider(); //初始化一只蜘蛛
    pMonster[2] = new Snake(); //初始化一条蛇
    
    for(int i=0; i<3; i++){
        pMonster[i] -> attack(); //攻击
    }

    双冒号(::)

    1、调用 namespace 中的成员时,需要用 ::

    2、在类的外部定义成员函数时,需要用::

    3、区别两个类中同名的成员变量或者函数时,需要用::

    4、在成员函数内部调用同名的全局变量时,需要用::

    5、调用类的静态成员函数时,可以用::

  • 相关阅读:
    苹果推送APNS自己总结
    Windows下LDAP服务器配置
    service mysql start出错,mysql启动不了,解决mysql: unrecognized service错误
    PHP 中的 9 个魔术方法
    使用 Equinox 开发 OSGi 应用程序
    使用 Equinox 框架进行 OSGi 环境下的 Web 开发
    探索 OSGi 框架的组件运行机制
    基于 OSGi 和 Spring 开发 Web 应用
    Equinox OSGI ServletBridge 原理与实践
    利用 Eclipse 开发基于 OSGi 的 Bundle 应用
  • 原文地址:https://www.cnblogs.com/netWild/p/8302514.html
Copyright © 2011-2022 走看看