我已经看到const关键字的很多用法放在类中的函数之后,所以我想知道它是什么。我在这里读了一下:http://duramecho.com/ComputerInformation/WhyHowCppConst.html。
它表示使用const是因为函数“可以尝试改变对象中的任何成员变量”。如果这是真的,那么它应该在任何地方使用,因为我不希望以任何方式改变或改变任何成员变量。
class Class2
{ void Method1() const;
int MemberVariable1;}
那么,const的真正定义和用途是什么?
答案 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限定符,它有助于捕获错误。
典型的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版本上调用此方法。