【问题标题】:c++ function syntax/prototype - data type after bracketsc++ 函数语法/原型 - 括号后的数据类型
【发布时间】:2023-03-28 02:29:01
【问题描述】:

我非常熟悉 C/C++ 标准函数声明。我最近看到了这样的事情:

int myfunction(char parameter) const

以上只是一个假设的例子,我什至不知道它是否有意义。我指的是参数之后的部分。常数。这是什么?

一个更真实的例子:

wxGridCellCoordsArray GetSelectedCells() const

这可以找到here 那么行尾的const 到底是做什么的呢?

【问题讨论】:

  • this
  • @chris 很好。但现在我很困惑。 GetSelectedCells 函数没有要更改的参数?
  • @itsols,它是一个成员函数。因此,它有一个参数。
  • 更新了答案以解释一些重要的区别。首先,将 const 添加到函数末尾会更改其签名,因此是函数的有效重载。其次,我解释了为什么使用 mutable 以及按位 const 和概念 const 之间的区别,以及一篇解释差异的写得很好的文章。希望这会有所帮助

标签: c++ function constants mutable function-signature


【解决方案1】:

const 关键字在函数之后显示时,可确保函数调用者不会更改任何成员数据变量。它还更改了函数签名,这是一些 C++ 程序员鲜为人知的事情。实际上,您可以通过在具有相同名称的函数后添加 const 关键字来重载 C++ 中的函数。例如:

void changeValue() const;
void changeValue();

上述两个函数都是有效的,并且相互重载。当用户在 const 和非 const 函数中调用这些函数时,我经常看到一些 C++ API 和框架使用这种重载来避免过多的编译错误。这是否是好的 C++ 软件工程还有待商榷。我想这是不好的做法,但最好知道它会改变函数签名。

例如给定这个类,

// In header
class Node {

public:

Node();

void changeValue() const;

~Node();

private:

int value;

};

// 在.cpp中

void Node::changeValue() const {
    this->value = 3; // This will error out because it is modifying member variables
}

此规则有一个例外。如果您声明成员数据变量是可变的,那么无论函数是否声明为 const,它都可以更改。使用 mutable 用于将对象声明为常量的罕见情况,但实际上具有需要更改选项的成员数据变量。它的一个潜在使用示例是缓存一个您可能不想重复原始计算的值。这通常很少见……但最好能意识到这一点。围绕 Mutable 的软件工程决策的一个很好的参考是按位 const 与概念 const 的概念。使用按位 const,程序员通知读者,当 const 存在时,如果没有 const_cast,该 const 对象的任何位都不会改变。对于概念 const,其想法是类的用户不应该关心可变变量的位是否应该改变,因为它不会影响用户感知的类的使用。这是一篇很好的文章,解释了使用 Mutable 的区别和起伏 - https://www.cprogramming.com/tutorial/const_correctness.html

例如给定这个类,

// In header
class Node {

public:

Node();

void changeValue() const;

~Node();

private:

mutable int value;

};

// 在.cpp中

void Node::changeValue() const {
    this->value = 3; // This will not error out because value is mutable
}

【讨论】:

  • 副作用包括输出,所以这并不完全正确。
  • 哇!知道了。谢谢:)
  • 既然你的答案被接受了,你可能应该提到你可以更改标记为 mutable 的数据成员,然后我会给你一个 +1
  • 我来自过去 :) 我使用 C 的日子可以追溯到 1990 年。但我不记得在任何地方使用过这个 mutable 关键字。它对我没有用。为什么我需要做这样的事情,比如声明某事是常数,然后在函数中说某事是可变的?不太明白这些新事物的原因......无论如何,谢谢。
  • @itsols:您可能想要使用mutable 的一个示例是您的对象是否具有“最后访问时间”时间戳变量。即使有人使用const 方法访问对象,您也希望能够更新该变量。
【解决方案2】:

方法后面的const关键字表示隐含的this参数(设置为用于调用该方法的对象的地址)指向一个常量对象。

在 C++ 中。成员函数可能如下所示:

class Foo {
    int x;
    mutable int y;
public:
    void bar ()       {
        Foo *me = this;          // * this is an implicit parameter
                                 //   that points to the instance used
                                 //   to call bar()
        assert(&x == &this->x);  // * accesses to class members are
                                 //   implicitly taken from this
        x = 1;                   // * can modify data members
    }
    void bar () const {
        // Foo *me = this;       // * error, since "bar() const" means
                                 //   this is a "const Foo *"
        const Foo *me = this;    // * ok
        // x = 1;                // * error, cannot modify non-mutable
                                 //   members of a "const Foo"
        y = 0;                   // * ok, since y is mutable
    }
};

C 中的类比函数分别是访问 struct Foo *const struct Foo *

struct Foo {
    int x;
    int y;
};

void Foo_bar (Foo *this)        { /* ... */ } /* can modify this->x and this->y */
void cFoo_bar (const Foo *this) { /* ... */ } /* cannot modify this->x nor this->y */

C 中没有 mutable 模拟。

【讨论】:

    【解决方案3】:

    这是一种“防御性编程”技术,可帮助您防范自己的编程错误。使用const 反对函数参数,您声明该函数不应修改该参数,并且添加const 会导致编译器阻止您无意中这样做。同样,如果您编写的成员函数不应更改类的任何 成员变量,那么您可以像这样声明整个函数const,它会阻止您这样做。

    它还有助于使您的代码自我记录。将const 添加到参数会告诉用户“此函数不会修改此参数”。将const 添加到成员函数告诉用户“此函数不会修改类的任何成员”(显式可变成员除外)。

    除了您真正需要的情况外,限制对某些东西的访问通常应该被认为是一件好事。这与您不经常以 root 身份登录自己的系统的原因完全相同,即使您可以这样做,并且如果您这样做了,您将拥有更多的权力。

    【讨论】:

    • 我喜欢这样 - “防御性”编程和自我记录。 +1 提示
    【解决方案4】:

    const 表示该函数不会更改 this 的任何数据成员,除非它们被标记为可变。
    只有成员函数可以标记为 const,这意味着函数内部不会更改任何成员。

    【讨论】:

    • 唯一的例外是 const_cast。但是,如果有人重视他们的工作,我怀疑他们会使用它 =D
    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2014-12-16
    相关资源
    最近更新 更多