为什么使用const函数很有用?

时间:2010-12-24 03:57:00

标签: c++ winapi visual-c++ const

如果只能读取变量但不能写入(类变量),为什么创建函数const是如此有用?

6 个答案:

答案 0 :(得分:3)

这样你就不会“意外”修改其中一个类变量。这只是一种安全措施。

(如果在 修改类的任何数据成员的函数之后使用const关键字 - 直接或通过另一个函数调用 - 您将收到编译错误。)

答案 1 :(得分:3)

如果你将const指针或const引用传递给你的类的实例,那么它只能调用类的const方法(如果有的话)。

显然,如果你从不打扰你的类型的const-correctness那么你可以忽略它。

我想它也可能有助于编译器在某些情况下优化事物,虽然我很怀疑,即使它确实有所帮助,允许小的改进(如果有的话)决定你如何编写代码将是一个不成熟的情况在大多数情况下进行优化。

答案 2 :(得分:1)

一个原因是const是病毒。这意味着如果代码的一部分是const-correct,那么代码的其余部分将不会与该部分互操作。

如果你忽略了const-correctness,那么你的类与其他库(从标准库开始)一起工作的可能性很小。

例如:

#include <vector>
#include <algorithm>

struct X
{
    int n;
    bool operator< (X b)
    { 
        return n < b.n;
    }
};

int main()
{
    std::vector<X> vec;
    std::sort(vec.begin(), vec.end());
}

使用codepad.org

In function 'const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&) [with _Tp = X]':
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2642:   instantiated from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<X*, __gnu_norm::vector<X, std::allocator<X> > >, __gnu_debug_def::vector<X, std::allocator<X> > >, _Size = int]'
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2713:   instantiated from 'void std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<X*, __gnu_norm::vector<X, std::allocator<X> > >, __gnu_debug_def::vector<X, std::allocator<X> > >]'
t.cpp:17:   instantiated from here
Line 90: error: no match for 'operator<' in '__a < __b'

stdlib兼容的比较运算符必须承诺不修改参数。如果在比较对象时实际上要改变对象,那么尝试对它们进行排序将是徒劳的。

另一个例子:你将无法通过const引用传递参数,这是传递大对象的传统方法。相反,你必须通过可修改的引用传递参数。现在你将无法将任何类型的临时工具传递给你的职能部门。

答案 3 :(得分:0)

如果你有一个const对象,它只允许const成员函数对它进行操作。

答案 4 :(得分:0)

您可以在代码而不是文档中表达调用者和被调用者之间的契约越多,编译器可以帮助您遵守该契约(从两端)。隐式this指针的常量是其中一个重要部分,因为它是所有其他参数指示符的常量。 (当然,按值传递参数的顶级常量不是合同的一部分)

答案 5 :(得分:0)

好处是您可以让编译器强制执行可以修改状态的位置。例如,如果您创建一个包含私有数据的类,并且除了构造函数之外的所有方法都是const,那么您将拥有一个不可变的数据类型。这样做的好处不是性能,而是语义之一。