修改const方法中的指针值

oop*_*ene 0 c++ const

看看这段非常简单的代码:

struct A { char* s; };

class B
{
    A* a;

    public: B(const char* s) : a(new A()) {
        int len = strlen(s);
        a->s = new char[len + 1];
        memcpy(a->s, s, len + 1);
    }

    ~B() { delete [] a->s; delete a; }

    const char* c_str() const { return a->s; }

    const B& to_upper() const {
        char* x = a->s;
        int len = strlen(x);
        for (int i = 0; i < len; i++)
        {
            char k = x[i];
            if (k >= 'a' && k <= 'z')
                x[i] -= 32;
        }
        a->say_hi();
        return *this;
    }
};

int main() {
    B b = "hola mundo";
    printf("%s\n", b.to_upper().c_str());
}
Run Code Online (Sandbox Code Playgroud)

有用!!我的问题是......为什么?

to_upper()方法是const,并通过"a"修改值指针.好吧,我无法做"a = nullptr;"之类的事情.因为编译器说:"你正在尝试修改只读对象"; 但它让我修改基础价值观.这种行为是否正确?不应该将"a"类型转换为"const A*",方法与const方法中"this"的类型转换为"const B*"的方式相同吗?

谢谢!

AnT*_*AnT 6

的方法的常量性转换到的常量性*this对象,这意味着内部to_upper的this指针具有类型const B *.这里的所有都是它的.不多也不少.例如,这与您在C语言中看到的效果没有什么不同.它使指针成为this->a常量,但它不会影响指针.

实际上,由您决定是否B传播到A指向的对象的常量this->a.这种语言让您完全自由地做出这个决定.它被称为"概念常数"(与"物理常数"或"逻辑常数"相对).编译器只观察并强制执行逻辑const,而constOOP 中关键字的用途远不止于此:它允许您在设计中实现概念常量的概念.

如果A对象被认为是其中不可或缺的一部分B,那么const的const也B应该意味着const的恒定性A.但这是你必须手动观察和强制执行的东西(或者某些智能指针类可以帮助你解决这个问题).

如果A对象是这恰好可以仅仅是一个独立的对象引用的B,那么常量性B,并不必然暗示的常量性A.

编译器不会对此做出任何决定,因为编译器不知道您尝试实现的对象关系.在你的设计中,我看到的方式,A对象实际上是一个不可分割的一部分B,这意味着你不应该声明你to_upper的const.它是一种修改功能.它将用户感知的内容更改为B.通过声明to_upper,const你基本上"撒谎"给用户.