在类的函数中使用'const'

时间:2010-01-28 19:46:53

标签: c++ oop class const

我已经看到const关键字的很多用法放在类中的函数之后,所以我想知道它是什么。我在这里读了一下:http://duramecho.com/ComputerInformation/WhyHowCppConst.html

它表示使用const是因为函数“可以尝试改变对象中的任何成员变量”。如果这是真的,那么它应该在任何地方使用,因为我不希望以任何方式改变或改变任何成员变量。

class Class2
{ void Method1() const;
  int MemberVariable1;} 

那么,const的真正定义和用途是什么?

7 个答案:

答案 0 :(得分:37)

可以在const对象上调用const方法:

class CL2
{
public:
    void const_method() const;
    void method();

private:
    int x;
};


const CL2 co;
CL2 o;

co.const_method();  // legal
co.method();        // illegal, can't call regular method on const object
o.const_method();   // legal, can call const method on a regulard object
o.method();         // legal

此外,它还告诉编译器const方法不应该改变对象的状态并且会捕获这些问题:

void CL2::const_method() const
{
    x = 3;   // illegal, can't modify a member in a const object
}

通过使用mutable修饰符,上述规则有一个例外,但是在进入该领域之前,你应该先熟悉const的正确性。

答案 1 :(得分:5)

其他人回答了关于const成员函数的问题的技术方面,但这里有一个更大的图景 - 这就是const correctness的想法。

长话短说,const正确性是关于澄清和强制执行代码的语义。举一个简单的例子。看看这个函数声明:

bool DoTheThing(char* message);

假设有人写了这个函数,你需要调用它。你知道DoTheThing()对你的char缓冲区做了什么吗?也许它只是将消息记录到文件中,或者它可能会更改字符串。通过查看函数声明,您无法分辨调用的语义。如果函数没有修改字符串,则声明const不正确。

使你的函数const也正确有实际价值。也就是说,根据调用的上下文,如果没有一些技巧,您可能无法调用const不正确的函数。例如,假设您知道DoTheThing()不会修改传递给它的字符串的内容,并且您有以下代码:

void MyFunction()
{
  std::string msg = "Hello, const correctness";
  DoTheThing(msg.c_str());
}

上述代码无法编译,因为msg.c_str()会返回const char*。为了使这段代码能够编译,你必须做这样的事情:

void MyFunction()
{
  std::string msg = "Hello, const correctness";
  DoTheThing(msg.begin());
}

......甚至更糟:

void MyFunction()
{
  std::string msg = "Hello, const correctness";
  DoTheThing(const_cast<char*>(msg.c_str()));
}

可以说,它们都不比原始代码“更好”。但是因为DoTheThing()是以一种不正确的方式编写的,所以你必须围绕它来修改代码。

答案 2 :(得分:4)

const,当附加到非静态类方法时,告诉编译器您的函数不会修改对象的内部状态。

这在两个方面很有用:

  • 如果您编写了在const方法中更改内部状态的代码,编译器会捕获错误,将编程错误从运行时移动到编译时。
  • 如果客户端代码在常量指针上调用非const方法,编译器会捕获错误,确保维护“不改变事物链”。

通常,您希望将所有非变异非静态类方法声明为const。这允许调用代码在指针上使用const限定符,它有助于捕获错误。

典型的C ++:您可以声明一个类成员变量“mutable”,然后从const方法中将其改为甚至

答案 3 :(得分:3)

意思是你向客户调用const函数成员保证对象的状态不会改变。因此,当您说成员函数是const时,意味着您在函数调用期间不会更改任何对象成员变量。

答案 4 :(得分:3)

不想让任何成员变量发生变化是很不寻常的,但是如果这是你的类需要的话,那么你应该把你所有的成员函数都变成const。

但是,您可能确实想要更改至少一些成员:

class A {
  private: 
    int val;
  public:
    A() : val(0) {}
    void Inc() { val++; }
    int GetVal() const { return val; };
};

现在,如果我创建了两个A:

的实例
A a1;
const A a2;

我可以说:

a1.GetVal();
a2.GetVal();

但我只能说:

a1.Inc();

尝试更改常量对象的值:

a2.Inc();

给出了编译错误。

答案 5 :(得分:2)

  

如果这是真的,那么它应该在任何地方使用,因为我不希望以任何方式改变或改变任何成员变量?

嗯,不。有时你想要实例方法来修改成员。例如,任何set方法显然都需要设置变量,因此不应该将const放在任何地方。但是如果你的对象的状态是完全不可变的,首先考虑一下根本没有实例(即静态类)是否更好,如果不是这样,那么就把所有内容const

答案 6 :(得分:2)

在方法之后使用的const关键字表示此方法不会修改调用它的对象。这样,可以在对象的const版本上调用此方法。