当成员值从指针更改为非指针时,C ++ const问题

时间:2018-10-17 17:17:48

标签: c++ const

我有两个类TestClassOtherClass,其中TestClass的类型为OtherClass的成员变量名为m_otherClass。请注意,声明为常量。

在下面提供的最小示例中;当m_otherClass是一个指针时,则所有内容都会编译并运行良好。如果将其更改为非指针,则会出现编译器错误(在最小的示例中将更改注释掉了):

“在常量对象上调用了非常量函数'setOtherMember'”

错误:将“ const OtherClass”作为“ this”参数传递会丢弃限定符[-fpermissive] m_otherClass.setOtherMember();

#include <iostream>
#include <memory>

class OtherClass {
public:
    void setOtherMember() {
        m_otherMember = 2;
        std::cout << "Other member is now 2" << std::endl;
    }

private:
    int m_otherMember = 0;
};


class TestClass {
public:
    TestClass(): m_otherClass(std::make_unique<OtherClass>())
//  TestClass()
    {}

    void myMethod() const {
        m_otherClass->setOtherMember();
//      m_otherClass.setOtherMember();
    }
private:
        std::unique_ptr<OtherClass> m_otherClass;
//      OtherClass m_otherClass; // If changing to this I get the error!!
};


int main() {
    TestClass testClass;
    testClass.myMethod();
    return 0;
}

这是因为myMethod()是const(然后保证不更改任何成员变量),而setOtherMember()是非const并正在更改OtherClass的成员变量,然后还间接地m_otherClass对象?

但是如果m_otherClass是指针,为什么这不会失败? 为何编译器错误说在未m_otherClass声明为const的情况下将'const OtherClass'传递为'this'参数失败了?

4 个答案:

答案 0 :(得分:3)

在大多数情况下,不允许使用const合格的成员函数来更改对象的成员状态。这意味着不能在该功能体中修改每个不可变的成员。在处理指针时,您只是说,您将不会修改指针值,而不是指针对象本身。这是因为指针的常量性不会在其指针上传播

在即将发布的标准中,可以使用propagate_const来更改此行为。

答案 1 :(得分:2)

一个更简单的示例来说明差异。

struct Foo { int m; };

const Foo f = {10}; 
f.m = 20; // Not allowed since modifying f.m modifies f.

struct Bar { int* p; };
int i = 10;
int j = 20;

const Bar b = {&i};

b.p = &j;    // Not allowed since modifying b.p modifies b.

*(b.p) = j;  // Allowed since it does not change b or b.p. It changes the value
             // of what b.p points to.

答案 2 :(得分:1)

  

但是如果m_otherClass是指针,为什么这不会失败?

因为修改const指针指向的对象是const正确的,只要它是指向非const的指针(例如您的情况)即可。

  

为什么未将m_otherClass声明为const时,编译器错误为什么将'const OtherClass'传递为'this'参数失败?

myMethod被声明为const。因此this是指向const的指针。因此,不管由左值命名的对象是否为const,左值this->m_otherClass都是const。

答案 3 :(得分:1)

将const放在方法上时,所有数据成员都被视为const。这就是为什么将OtherClass作为值时会出现错误的原因,因为它变成了const OtherClass的值。

现在,当您使用指针OtherClass时,会得到const std::unique_ptr<OtherClass>,而const仅适用于指针,而不适用于其指向的值。