为什么像const这样的修饰符不能用于非成员函数

5

我不明白为什么不允许在非成员函数中使用诸如constvolatile之类的修饰符。

以下是我尝试过的示例代码:

class A
{
private:
    int var;
public:
    int func();
};

int A::func()
{
    // Some calculation on using var
    int temp = var + 10;
    return temp;
}

void func2( const A& tempObj ) const;

void func2( const A& tempObj ) 
{
    std::cout << "temp obj called : " << tempObj.func() << std::endl;
}

int main()
{
    A aobj;
    aobj.func();
    func2( aobj );
    return 0;
}

这会导致编译器错误 error C2270: 'func2' : modifiers not allowed on nonmember functions,针对的是void func2( const A& tempObj ) const;

我还遇到了另一个错误 error C2662: 'A::func' : cannot convert 'this' pointer from 'const A' to 'A &',出现在 func2 中的 tempObj.func(),我原本以为会无误地调用成员函数 func


还请帮助他理解无法将'this'指针从'const A'转换为'A&'。我认为这里的转换是相反的。 - Krishna Oza
1
你能解释一下你期望这个修饰符的含义吗? - Angew is no longer proud of SO
@Krishna_Oza 那没有回答这个问题。 - juanchopanza
1
我已经检查了更新,你只是添加了另一个问题,但没有回答我的问题。你认为在非成员函数上使用const限定符会有什么意义? - Angew is no longer proud of SO
1
@Krishna_Oza 这就是 const A&const 的目的。 - Angew is no longer proud of SO
显示剩余7条评论
4个回答

15

const修饰符表示成员函数不会修改该函数所属对象的数据成员。

这就像一个保证,调用对象aobj上的该函数不会修改该对象的内部状态。因此,假设aobj也被声明为const,你仍然可以在其上调用该函数;相反,你将无法调用非const函数成员。

如果一个函数不是类的成员,将const修饰符应用于它是没有意义的。在另一种语言中,这可能意味着该函数无法修改全局变量;但这种语言并不是C++。


5

想象一下,每个非静态成员函数都有一个隐藏的参数:

int A::func(A* this) {...}

如果你将成员函数声明为const或volatile,它会被添加到一个隐藏参数中,类似于以下操作:

int A::func(const A* this) {...}

有些语言(如Python)会明确指定成员函数的实例参数,因此在类定义中写入def func(self):来声明非静态函数。


3
在C++中,成员函数修饰符应用于调用函数的对象。这就是语言对这些修饰符的使用方式。
非成员函数没有这样的对象,因此资格不会有意义。可以想象语言允许cv修饰非成员函数没有效果,但在我的看法中,这只会令人困惑。也可以想象cv限定符对非成员有不同的含义,但现实是现实,语言是按照设计的方式运行的。

@davidhigh 没错,但是“为什么非成员函数不允许使用const等修饰符”的答案是因为这些修饰符适用于对象本身,而不是其他任何东西。 - juanchopanza
2
@davidhigh,现实中,这种限制将作为“纯”的一部分出现,这已经被提出,并且至少GCC有一个属性。 - chris
@juanchopanza 我认为关于不允许在成员函数中使用 const 的解释相当回答了我的问题,但是你能帮我理解为什么从 func2 声明中删除 const 后,我无法调用 tempObj.func() 或者会出现错误吗? - Krishna Oza
1
@Krishna_Oza A::func() 不是一个 const 成员函数,因此它不能通过 const 引用调用。 - juanchopanza
1
@Krishna_Oza 不行。在你的情况下,“this”指针是tempObj,也就是一个const A。但你试图在它上面调用一个非const函数,这需要一个“this”的A&。因此,这是从const A&A&的转换失败了。 - Angew is no longer proud of SO
显示剩余4条评论

3

const 限定符用于类方法,声明该方法不会修改任何(非可变)成员变量。

因此,在非成员函数上声明它是没有任何意义的,因为它没有成员变量可以修改。

const 限定符非常有用,因为它明确表示可以在 const 变量上调用此方法,而不会违反该变量的常量性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接