谈谈const

const member functions (常量成员函数)

告诉编译器,该成员函数不能改变类的成员变量

项目 const object(常量对象 data members不能改变) non-const object(非常量对象 data members可以改变)
const member functions(保证不更改data members) yes yes
non-const member functions(不保证data members不变) no yes

当成员函数的const和non-const版本同时存在,const object只能调用const版本,non-const object只能调用non-const版本;

class template std::basic_string<…> 有如下两个member functions:
charT operator[](size_type pos) const { /不必考虑 Copy on Write / }
reference operator[](size_type pos) { /必须考虑 Copy on Write / }

string 采用的是计数模式,所以一个相同内容相同的变量会共享。上面的两个函数,可能被拿来修改数据,所以里面需要做Copy on Write,即:假如str1,str2,str3的内容都是”aaaaa”,那么他们三个会共享”aaaaaa”,但是其中某个字符串要修改内容,str1要修改字符串中的第二个字符为’b’,则会先复制一份”aaaaaa”,然后修改成”abaaaa”。这时候str2和str3还是会共享”aaaaaa”,但是str1则不会,其值为”abaaaa”。

看下面一个例子:

代码1

class Test {
public:
    void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    //void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    Test test;
    test.fun(1);
    return 0;
}

输出结果:
fun non-const

代码2

class Test {
public:
    //void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    Test test;
    test.fun(1);
    return 0;
}

输出结果:
i: 1 fun const

上面两个代码测试,可以看出,非const的对象既可以调用常量成员函数,也可以调用非常量成员函数。那如果这两个函数同时存在,会构成重载嘛?如果构成重载,非const的对象会调用那一个呢?看下面代码…

代码3

class Test {
public:
    void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    Test test;
    test.fun(1);
    return 0;
}

输出结果:
i: 1 fun non-const

代码3顺利编译通过,并运行输出i: 1 fun non-const,说明:在常量成员函数和非常量成员函数同时存在的时候,非常量对象会调用非常量成员函数。

代码4

class Test {
public:
    void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    //void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    const Test constTest;
    constTest.fun(2);
    return 0;
}


编译出错:
error: member function 'fun' not viable: 'this' argument has type 'const Test', but function is not marked const
        constTest.fun(2);

常量对象调用非常量成员函数,编译不通过。

代码5

class Test {
public:
    //void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    const Test constTest;
    constTest.fun(2);
    return 0;
}

输出结果:
i: 2 fun const

常量对象调用常量成员函数,没有问题。 但是如果:常量成员函数和非常量成员函数都存在的时候,常量对象会调用那个呢?

代码6

class Test {
public:
    void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    const Test constTest;
    constTest.fun(2);
    return 0;
}

输出结果:
i: 2 fun const

常量成员函数和非常量成员函数都存在的时候,常量对象将调用常量成员函数。

代码7

class Test {
public:
    void fun(int i) { cout << "i: " << i << " fun non-const" << endl; }
    void fun(int i) const { cout << "i: " << i << " fun const" << endl; }
};

int main(int argc, char *argv[]) {
    Test test;
    test.fun(1);

    const Test constTest;
    constTest.fun(2);
    return 0;
}

输出结果:
i: 1 fun non-const
i: 2 fun const

常量成员函数和非常量成员函数都存在的时候,非常量对象将调用非常量成员函数,常量对象将调用常量成员函数。

总结:
1. const修饰的成员函数,不仅限制函数去修改成员变量,同时也可以实现函数的重载
2. const修饰的成员函数,如果没有被重载,那么非const对象和const对象都可以调用;
3. const修饰的成员函数,如果被重载了,非const对象只能调用没有被const修饰的成员函数,const对象也只能调用被const修饰的成员函数。

猜你喜欢

转载自blog.csdn.net/lmb1612977696/article/details/80033764
今日推荐