• c++面向对象 之 基础 类修饰符 构造函数 友元函数


    1,类和对象

    定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。

    类定义格式如下:

    class Box
    {
    public:    //在类对象作用域内,公共成员在类的外部是可访问的。
    double length; // 盒子的长度
    double breadth; // 盒子的宽度
    double height; // 盒子的高度
    };

    声明类对象:

    Box Box1; // 声明 Box1,类型为 Box
    Box Box2; // 声明 Box2,类型为 Box

    访问数据成员:

    #include <iostream>
    using namespace std;
    class Box
    {
    public:
    double length; // 长度
    double breadth; // 宽度
    double height; // 高度
    };
    int main( )
    {
    Box Box1; // 声明 Box1,类型为 Box
    Box Box2; // 声明 Box2,类型为 Box
    double volume = 0.0; // 用于存储体积
    // box 1 详述
    Box1.height = 5.0;    //为实例的某个属性赋值,采用点号
    Box1.length = 6.0;
    Box1.breadth = 7.0;
    // box 2 详述
    Box2.height = 10.0;
    Box2.length = 12.0;
    Box2.breadth = 13.0;
    // box 1 的体积
    volume = Box1.height * Box1.length * Box1.breadth;    //访问某个实例的类中的某个属性,同样用点号,当然还要看共有还是私有
    cout << "Box1 的体积:" << volume <<endl;
    // box 2 的体积
    volume = Box2.height * Box2.length * Box2.breadth;
    cout << "Box2 的体积:" << volume <<endl;
    return 0;
    }

    定义类成员函数:

    内部定义成员函数:

    class Box
    {
    public:
    double length; // 长度
    double breadth; // 宽度
    double height; // 高度
    double getVolume(void)
    {
    return length * breadth * height;
    }
    };

    外部定义成员函数,必须要使用范围解析运算符:

    double Box::getVolume(void)    //类名::函数名
    {
    return length * breadth * height;
    }

    在外部定义内联的成员函数,那么你需要一个关键字:inline

    class A
    {
        public:void Foo(int x, int y) {  } // 自动地成为内联函数
    }
    
    
    // 头文件
    class A
    {
        public:
        void Foo(int x, int y);
    }
    // 定义文件,这个也是内联函数,注意inline必须与函数定义放在一块
    inline void A::Foo(int x, int y){} 

    调用成员函数:

    #include <iostream>
    using namespace std;
    class Box
    {
    public:
    double length; // 长度
    double breadth; // 宽度
    double height; // 高度
    // 成员函数声明
    double getVolume(void);
    void setLength( double len );
    void setBreadth( double bre );
    void setHeight( double hei );
    };
    // 成员函数定义
    double Box::getVolume(void)
    {
    return length * breadth * height;
    }
    void Box::setLength( double len )
    {
    length = len;
    }
    void Box::setBreadth( double bre )
    {
    breadth = bre;
    }
    void Box::setHeight( double hei )
    {
    height = hei;
    }
    // 程序的主函数
    int main( )
    {
    Box Box1; // 声明 Box1,类型为 Box
    Box Box2; // 声明 Box2,类型为 Box
    double volume = 0.0; // 用于存储体积
    // box 1 详述
    Box1.setLength(6.0);
    Box1.setBreadth(7.0);
    Box1.setHeight(5.0);
    // box 2 详述
    Box2.setLength(12.0);
    Box2.setBreadth(13.0);
    Box2.setHeight(10.0);
    // box 1 的体积
    volume = Box1.getVolume();
    cout << "Box1 的体积:" << volume <<endl;
    // box 2 的体积
    volume = Box2.getVolume();
    cout << "Box2 的体积:" << volume <<endl;
    return 0;
    }

     2,类访问修饰符

    class Base {
    public:
    // 公有成员,
    protected:
    // 受保护成员
    private:
    // 私有成员
    };

    public:

    #include <iostream> 
    using namespace std; 
    class Line
    {
       public:
          double length;
          void setLength( double len );    //声明成员函数
          double getLength( void );    
    };
     
    // 成员函数定义
    double Line::getLength(void)    //外部实现成员函数
    {
        return length ;
    } 
    void Line::setLength( double len )
    {
        length = len;
    } 
    // 程序的主函数
    int main( )
    {
       Line line; 
       // 设置长度
       line.setLength(6.0);     //public支持使用类自带的成员函数修改属性值
       cout << "Length of line : " << line.getLength() <<endl; 
       //public同样支持在外部直接赋值类的属性 
       line.length = 10.0; // OK: 因为 length 是公有的
       cout << "Length of line : " << line.length <<endl;
       return 0;
    }

    private:

    #include <iostream>
     
    using namespace std;
     
    class Box
    {
       public:
          double length;
          void setWidth( double wid );
          double getWidth( void );
     
       private:
          double width;
    };
     
    // 成员函数定义,成员函数属于公有,但是操作的是私有的属性
    double Box::getWidth(void)
    {
        return width ;
    }
     
    void Box::setWidth( double wid )
    {
        width = wid;
    }
     
    // 程序的主函数
    int main( )
    {
       Box box;
     
       // 对于私有变量width来说,不使用成员函数设置宽度是不行的
       // box.width = 10.0; // Error: 因为 width 是私有的
       box.setWidth(10.0);  // 只能使用成员函数设置宽度,也就是说私有的属性只有通过它自己定义的方法才能改变,外部不能改变它。
       cout << "Width of box : " << box.getWidth() <<endl;
       return 0;
    }

    protected:只有自己或者子类的成员函数才能访问

    #include <iostream>
    using namespace std;
     
    class Box
    {
       protected:
          double width;
    };
     
    class SmallBox:Box // SmallBox 是派生类
    {
       public:
          void setSmallWidth( double wid );
          double getSmallWidth( void );
    };
     
    // 子类的成员函数
    double SmallBox::getSmallWidth(void)
    {
        return width ;
    }
    void SmallBox::setSmallWidth( double wid )
    {
        width = wid;
    }
    // 程序的主函数
    int main( )
    {
       SmallBox box;
       // 使用成员函数设置宽度
       box.setSmallWidth(5.0);
       cout << "Width of box : "<< box.getSmallWidth() << endl;
       return 0;
    }
    • 1.private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;

    • 2.protected 成员可以被派生类访问。

     3,构造函数和析构函数

    构造函数:

    c++中构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。

    #include <iostream>
     
    using namespace std;
     
    class Line
    {
       public:
          void setLength( double len );
          double getLength( void );
          Line();  // 这是构造函数,构造函数里带参数也是可以的,就和普通函数带参数一样
     
       private:
          double length;
    };
     
    // 成员函数定义,包括构造函数
    Line::Line(void)    //定义构造函数,在class里直接定义也行。
    {
        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;
    }
    //假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同时初始化多个属性
    C::C( double a, double b, double c): X(a), Y(b), Z(c)
    {
      ....
    }

    析构函数:

    类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。

    析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

    #include <iostream>
     
    using namespace std;
     
    class Line
    {
       public:
          void setLength( double len );
          double getLength( void );
          Line();   // 这是构造函数声明
          ~Line();  // 这是析构函数声明
     
       private:
          double length;
    };
     
    // 成员函数定义,包括构造函数
    Line::Line(void)
    {
        cout << "Object is being created" << endl;
    }
    Line::~Line(void)
    {
        cout << "Object is being deleted" << 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;
       //line.~Line();    这样也是可以滴,手动析构以后系统还是会再检查一遍
       return 0;
    }

     4,拷贝构造函数

    其实就是拷贝一个对象的实例,尽管听起来简单,但是拷贝的时候一定要注意指针或者引用等,小心语法错误

    #include <iostream>
    //拷贝构造函数
    using namespace std;
     
    class Line
    {
       public:
          int getLength( void );
          Line( int len );             // 简单的构造函数
          Line( const Line &obj);      // 拷贝构造函数
          ~Line();                     // 析构函数
     
       private:
          int *ptr;
    };
     
    // 在对象的外部定义函数内容,成员函数定义,包括构造函数
    Line::Line(int len)
    {
        cout << "调用构造函数" << endl;
        // 为指针分配内存
        ptr = new int;    //新建一个int数据类型
        *ptr = len;
    }
     
    Line::Line(const Line &obj)    //指明了要拷贝的是line这个对象,因为这个对象已经被构造过了
    {
        cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
        ptr = new int;
        *ptr = *obj.ptr; //为啥是指针呢,因为ptr是个指针,相当于*(obj.ptr)
    }
     
    Line::~Line(void)
    {
        cout << "释放内存" << endl;
        delete ptr;
    }
    int Line::getLength( void )
    {
        return *ptr;
    }
     
    void display(Line obj)
    {
       cout << "line 大小 : " << obj.getLength() <<endl;
    }
     
    // 程序的主函数
    int main( )
    {
       Line line(10);
     
       display(line);
     
       return 0;
    }

    返回:

    调用构造函数
    调用拷贝构造函数并为指针 ptr 分配内存
    line 大小 : 10
    释放内存
    释放内存
    //函数声明等一致的情况下,拷贝构造函数也可以是直接复制实例
    //接上一个函数
    // 程序的主函数
    int main( )
    {
       Line line1(10);
     
       Line line2 = line1; // 这里也调用了拷贝构造函数
     
       display(line1);
       display(line2);
     
       return 0;
    }

    返回是这样的:

    调用构造函数
    调用拷贝构造函数并为指针 ptr 分配内存
    调用拷贝构造函数并为指针 ptr 分配内存
    line 大小 : 10
    释放内存
    调用拷贝构造函数并为指针 ptr 分配内存
    line 大小 : 10
    释放内存
    释放内存
    释放内存

    5,友元函数

    友元函数不是类的成员函数,而是定义在类的外部,但是又能访问私有和保护成员的函数,友元函数用friend指定。

    class Box
    {
       double width;
    public:
       double length;
       friend void printWidth( Box box );
       void setWidth( double wid );
    };
    #include <iostream>
     
    using namespace std;
     
    class Box
    {
       double width;
    public:
       friend void printWidth( Box box );    //注意此处的友元函数传递的参数是类实例哦。
       void setWidth( double wid );
    };
    
    // 成员函数定义
    void Box::setWidth( double wid )
    {
        width = wid;
    }
    
    // 请注意:printWidth() 不是任何类的成员函数
    void printWidth( Box box )
    {
       /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
       cout << "Width of box : " << box.width <<endl;
    }
     
    // 程序的主函数
    int main( )
    {
       Box box;
     
       // 使用成员函数设置宽度
       box.setWidth(10.0);
       
       // 使用友元函数输出宽度
       printWidth( box );
     
       return 0;
    }
  • 相关阅读:
    冬至——汤圆
    偷偷的高兴!
    sql 70229 考试样题(2)
    SQL Server开发人员应聘常被问的问题妙解汇总
    GOOLE Picasa Web License
    辞旧迎新!
    VC98\mfc\lib' specified in 'LIB environment variable' 系统找不到指定路径
    ASP 入门
    OpenCV类型转换
    坐标旋转变换公式的推导
  • 原文地址:https://www.cnblogs.com/0-lingdu/p/10675192.html
Copyright © 2020-2023  润新知