zoukankan      html  css  js  c++  java
  • 常对象成员和常成员函数

    -----------------siwuxie095

       

       

       

       

       

       

       

       

       

    常对象成员 和 常成员函数

       

       

    看如下实例:

       

    定义一个坐标类:Coordinate

       

       

       

       

    要想正确的初始化,必须通过初始化列表来初始化,因为两个数据成员

    都是由 const 来修饰的,是常数据成员

       

       

       

    作为一个类的数据成员来说,是可以用 const 来修饰的

       

    显然,对象作为数据成员,也是可以用 const 来修饰的,称之为 常对象成员

       

       

    以线段为例:当线段的位置一旦确定,就不能再更改

       

       

       

       

       

    定义一个线段类:

       

    因为要实现两个点一旦初始化,就不能再修改,需要定义成 const

       

       

       

       

    在构造函数中通过初始化列表来初始化:

       

       

       

       

    在使用时:

       

       

       

       

       

    const 不仅可以修饰数据成员,还可以修饰成员函数

       

    const 修饰的成员函数,称之为 常成员函数

       

    「常成员函数中,const 修饰的实际上就是 this 指针」

       

       

    看如下实例:

       

       

       

    定义 changeX() 函数:上面的写法是错误的,下面的写法是正确的

       

       

       

       

    常成员函数中为什么不能修改数据成员的值呢?

       

    当定义 changeX() 函数时,看上去没有任何的参数,而实际上

    却隐含着一个参数:this 指针

       

       

       

       

    当成员函数不是一个普通的成员函数,而是一个 const 修饰过的

    常成员函数时,依然有一个隐含的参数:this 指针,但 this 指针

    是用 const 来修饰的,是一个常指针。通过常指针去改变该指针

    指向的数据,肯定是不被允许的

       

       

       

    所以,如果在常成员函数中去修改数据成员的值,这种做法就一定是错误的

       

       

       

    此外,changeX() 和 changeX() const 二者互为重载

       

       

       

       

    虽然从语法的角度来说,这个的确可以有,但如果真要去这么定义的话,

    那我还是挺佩服你的,就像佩服孔乙己知道 字有 4 种写法一样

       

    因为这样定义,接下来在使用时,肯定会感到疑惑:调用的是哪个成员

    函数?实际上调用的是不带 const 的普通的成员函数 changeX()

       

       

       

       

    那么在什么情况下可以调用常成员函数?

       

    在实例化对象时,必须用 const 来修饰这个对象,这样实例化的

    对象,称之为 常对象

       

    通过常对象调用的 changeX(),就是用 const 修饰的常成员函数

       

       

       

       

       

       

    程序:

       

    Coordinate.h:

       

    class Coordinate

    {

    public:

    Coordinate(int x,int y);

    ~Coordinate();

    void setX(int x);

    //const修饰后只具有只读权限所以可以修饰get函数

    //相当于 int getX(const Coordinate *this);

    int getX() const;

    //set函数具有写权限所以不能用const(不能修改函数里面的值)修饰

    void setY(int y);

    int getY() const;

    private:

    int m_iX;

    int m_iY;

    };

       

       

       

    Coordinate.cpp:

       

    #include "Coordinate.h"

    #include <iostream>

    using namespace std;

       

       

    Coordinate::Coordinate(int x, int y)

    {

    m_iX = x;

    m_iY = y;

    cout << "Coordinate() " << m_iX << "," << m_iY << endl;

    }

       

    Coordinate::~Coordinate()

    {

    cout << "~Coordinate() " << m_iX << "," << m_iY << endl;

    }

       

    void Coordinate::setX(int x)

    {

    m_iX = x;

    }

       

    int Coordinate::getX() const

    {

    return m_iX;

    }

       

    void Coordinate::setY(int y)

    {

    m_iY = y;

    }

       

    int Coordinate::getY() const

    {

    return m_iY;

    }

       

       

       

    Line.h:

       

    #include "Coordinate.h"

       

    class Line

    {

    public:

    Line(int x1,int y1,int x2,int y2);

    ~Line();

    void setA(int x, int y);

    void setB(int x, int y);

    //常成员函数注意:const和括号之间要隔开一个空格不然有些编译器下可能无法通过

    //相当于 void printInfo(const Coordinate *this);

    //也就是说常成员函数的const实际上修饰的是this指针使之成为常this指针

    void printInfo() const;

    // void printInfo(Coordinate *this); 隐藏的this指针

    //同名的普通成员函数和常成员函数互为重载

    void printInfo();

    private:

    const Coordinate m_coorA;//一个常对象成员

    Coordinate m_coorB; //一个对象成员

    };

       

       

       

    Line.cpp:

       

    #include "Line.h"

    #include <iostream>

    using namespace std;

       

       

    Line::Line(int x1, int y1, int x2, int y2) :m_coorA(x1, y1), m_coorB(x2, y2)

    {

    cout << "Line()" << endl;

    }

       

    Line::~Line()

    {

    cout << "~Line()" << endl;

    }

       

    void Line::setA(int x, int y)

    {

    //m_coorA是常对象成员无法使用普通成员函数使用导致报错

    //因为:setX(int x); 相当于 setX(Coordinate *this,int x);

    //传进去的是m_coorA的常this指针(只读)m_coorA是个只具有读权限的对象

    //而原函数里的this既有读权限又有写权限

    //

    //m_coorA.setX(x);

    //m_coorA.setY(y);

    }

       

    void Line::setB(int x, int y)

    {

    m_coorB.setX(x);

    m_coorB.setY(y);

    }

       

    void Line::printInfo() const

    {

    cout << "printInfo() const" << endl;

    cout << "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" << endl;

    cout << "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" << endl;

    }

       

    void Line::printInfo()

    {

    cout << "printInfo()" << endl;

    cout << "(" << m_coorA.getX() << "," << m_coorA.getY() << ")" << endl;

    cout << "(" << m_coorB.getX() << "," << m_coorB.getY() << ")" << endl;

    }

       

       

       

    main.cpp:

       

    #include <stdlib.h>

    #include "Line.h"

    using namespace std;

       

       

    int main(void)

    {

    Line line1(1, 2, 3, 4);

    line1.printInfo();//调用的是不带constprintInfo()

    const Line line2(5, 6, 7, 8);

    line2.printInfo();//调用的是带constprintInfo()

    system("pause");

    return 0;

    }

       

    //即常对象和常对象成员只能调用常成员函数

    //而普通的对象和对象成员却可以调用普通成员函数和常成员函数

    //

    //常数据成员和常对象成员必须使用初始化列表初始化

    //(即const修饰的数据成员和对象成员在构造函数中只能用初始化列表初始化)

    //同名的普通成员函数和常成员函数互为重载

       

       

    运行一览:

       

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    2019年金秋第八周助教小结
    2019年金秋第七周助教小结
    2019年金秋第五周助教小结
    2019年金秋第四周助教小结
    2019年金秋第三周助教小结
    Java实验报告(一)
    L1-049 天梯赛座位分配 (20 分)
    助教个人总结
    【CF603E】Pastoral Oddities
    机房人物列传
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6798391.html
Copyright © 2011-2022 走看看