Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用';常数';课堂上';s函数_C++_Oop_Class_Constants - Fatal编程技术网

C++ 使用';常数';课堂上';s函数

C++ 使用';常数';课堂上';s函数,c++,oop,class,constants,C++,Oop,Class,Constants,我已经在类中看到了很多在函数之后放置const关键字的用法,所以我想知道它是关于什么的。我在这里读到了smth: 它说使用const是因为函数“可以尝试更改对象中的任何成员变量”。如果这是真的,那么它应该在任何地方使用,因为我不希望任何成员变量以任何方式被改变或改变 class Class2 { void Method1() const; int MemberVariable1;} 那么,const的真正定义和用途是什么 如果这是真的,那么它应该在任何地方使用,因为我不希望任何成员变量以

我已经在类中看到了很多在函数之后放置const关键字的用法,所以我想知道它是关于什么的。我在这里读到了smth:

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

class Class2
{ void Method1() const;
  int MemberVariable1;} 
那么,const的真正定义和用途是什么

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


不,有时您确实需要实例方法来修改成员。例如,任何set方法显然都需要设置变量,因此不应该将const放在任何地方。但是,如果对象的状态是完全不可变的,首先考虑是否根本没有实例(即静态类)更好,如果不是这样的话,那么使所有的东西都成为代码> const 。< /P> < P>这意味着您可以保证客户端调用一个const函数成员,对象的状态不会改变。因此,当您说成员函数是常量时,这意味着您在函数调用期间不更改任何对象成员变量。

不希望更改任何成员变量是很不寻常的,但是如果这是您的类所要求的,那么您应该使所有成员函数都是常量

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

class A {
  private: 
    int val;
  public:
    A() : val(0) {}
    void Inc() { val++; }
    int GetVal() const { return val; };
};
现在,如果我创建一个的两个实例:

A a1;
const A a2;
我可以说:

a1.GetVal();
a2.GetVal();
但我只能说:

a1.Inc();
尝试更改常量对象的值:

a2.Inc();

给出编译错误。

可以对常量对象调用常量方法:

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
}

上述规则有一个例外,即使用可变修饰符,但在进入该领域之前,您应该首先掌握const的正确性。

方法后使用的const关键字表示该方法不修改调用它的对象。通过这种方式,可以对对象的const版本调用此方法。

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

这在两个方面很有用:

  • 如果您确实编写了更改const方法内部状态的代码,编译器将捕获错误,从而将编程错误从运行时转移到编译时
  • 如果客户机代码调用常量指针上的非常量方法,编译器将捕获错误,确保“不变链”得到维护
通常,您希望将所有非变异的非静态类方法声明为const。这允许调用代码在指针上使用常量限定符,并有助于捕获错误


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

其他人已经回答了您关于const成员函数的问题的技术方面,但这里有一个更大的图景——这就是

长话短说,const correction是关于澄清和加强代码的语义。举个简单的例子。查看此函数声明:

bool DoTheThing(char* message);
假设其他人编写了这个函数,您需要调用它。你知道
DoTheThing()
对你的字符缓冲区有什么影响吗?也许它只是将消息记录到一个文件中,或者它更改了字符串。您不能仅仅通过查看函数声明就知道调用的语义是什么。如果函数不修改字符串,则声明不正确

使函数常量正确也有实用价值。也就是说,根据调用的上下文,如果没有一些技巧,您可能无法调用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()));
}
void MyFunction()
{
std::string msg=“你好,const correction”;
DoTheThing(const_cast(msg.c_str());
}

可以说,这两者都不比原始代码“更好”。但是因为
DoTheThing()
是以一种不正确的方式编写的,所以您必须将代码绕过它。

如果您的成员变量从未更改,为什么会有成员变量?因为他想要一个不可变的类?这不是没有道理的。我不是一个真正的C++人,所以它更像是一个有趣的问题,而不是一个“难题”。如果您希望所有成员都是不可变的,为什么不将其声明为“const”?或者你们两个都将成员声明为const,将方法声明为const?我可能只是将方法声明为const,但你们两个都可以。不过,这并不是一个可以在评论中描述的话题。@GMan:令人遗憾的是,人们根据预期的“声誉收入”而不是仅仅帮助需要帮助的人回答问题。这并不完全正确-可观察的行为不会改变,但如果标记为
可变的
,则成员数据可以改变。例如,这允许缓存一次计算的结果,甚至更糟。如果有一个指针指向某些数据,则成员函数后面的
const
只能保证指针不被更改,而不是它所指向的数据。但是,数据通常被视为对象状态的一部分。因此,实际上,
const
仅阻止成员函数更改对象的成员数据,而不是其所有状态。它强制执行位智能常量