常量和非常量 getter 具有相同的名称

const and non-const getter with same name

本文关键字:常量 非常 getter      更新时间:2023-10-16

考虑以下类:

class ConstTest
{
public:
ConstTest() : myPrivateData(42) {}
const int* getMyPrivateData() const {std::cout << "const" << std::endl; return &myPrivateData;}
int* getMyPrivateData() {std::cout << "non-const" << std::endl; return &myPrivateData;}
private:
int myPrivateData;
};

是否有任何规则在哪个上下文中使用哪个 getter。我的印象是,只有在常量环境中,常量吸气剂才会被调用。谁能证实这一点?我非常感谢官方来源,因为我想依靠该功能。

编辑:

我知道我可以尝试一下。但是在标准方面我可以依靠它吗?

我知道

我可以尝试一下。但是在标准方面我可以依靠它吗?

over.match.funcs/4+5:

  1. 对于非静态成员函数,隐式对象参数的类型为

    • "对 cv X 的左值引用",用于声明没有 ref-qualifier 或 & ref-qualifier 的函数

    • "对 cv X 的右值引用",用于使用 &&ref-限定符声明的函数

      其中 X 是函数所属的类,cv 是成员函数声明的 cv 限定。[ 示例:对于类 X 的 const 成员函数,假定额外参数的类型为"对 const X 的引用"。对于转换函数,该函数被视为隐含对象参数类的成员,目的是定义隐式对象参数的类型。对于由 using-声明引入派生类的非转换函数,该函数被视为派生类的成员,目的是定义隐式对象参数的类型。对于静态成员函数,隐式对象参数被视为匹配任何对象(因为如果选择了该函数,则会丢弃该对象(。[ 注意:没有为静态成员函数的隐式对象参数建立实际类型,也不会尝试确定该参数的转换顺序([over.match.best](。

  2. 在重载解析期间,隐含对象参数与其他参数没有区别。但是,隐式对象参数保留其标识,因为无法应用用户定义的转换来实现与其的类型匹配。

没错。因此,如果您有这样的代码:

ConstTest a;
a.getMyPrivateData();
const ConstTest b;
b.getMyPrivateData();

它打印:

non-const
const

这同样适用于其他修饰符,例如volatile.因此,您的类还可以使用另一种方法来处理volatile情况:

class ConstTest
{
public:
ConstTest() : myPrivateData(42) {}
const int* getMyPrivateData() const {std::cout << "const" << std::endl; return &myPrivateData;}
int getMyPrivateData() volatile {std::cout << "volatile" << std::endl; return volatilePrivateData;}
int* getMyPrivateData() {std::cout << "non-const" << std::endl; return &myPrivateData;}
private:
int myPrivateData;
volatile int volatilePrivateData;
};

而这段代码:

ConstTest a;
a.getMyPrivateData();
const ConstTest b;
b.getMyPrivateData();
volatile ConstTest c;
c.getMyPrivateData();

指纹:

non-const
const
volatile

您可以自己测试:

#include <iostream>
class ConstTest
{
public:
ConstTest() : myPrivateData(42) {}
const int* getMyPrivateData() const {std::cout << "const" << std::endl; return &myPrivateData;}
int* getMyPrivateData() {std::cout << "non-const" << std::endl; return &myPrivateData;}
private:
int myPrivateData;
};
int main()
{
auto a = ConstTest();
const auto b = ConstTest();
a.getMyPrivateData();
b.getMyPrivateData();
}

设计允许这样做的一个很好的指示是标准库使用它。

例如,请参阅std::vector::data

T* data() noexcept;
const T* data() const noexcept;