在const方法中修改Pointee值 [英] Modifying the pointee value in a const method

查看:50
本文介绍了在const方法中修改Pointee值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Look at this very simple piece of code:

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());
}

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

It works!! My question is... why?

to_upper()方法是const,并通过"a"修改值pointee.好的,我无法执行类似"a = nullptr;"的操作因为编译器说:您正在尝试修改只读对象";但这让我可以修改基础价值.这种行为正确吗?

The to_upper() method is const and modifies the value pointee by "a". Ok, I am not able to do something like "a = nullptr;" because the compiler says: "You are trying to modify a read-only object"; but it lets me modifying the underlying values. Is this behavior correct? Shouldn't the "a" type be converted to "const A*" in the same way that the type of "this" is converted to "const B*" in the const method?

谢谢!

推荐答案

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

The constness of a method translates to the constness of the *this object, meaning that inside to_upper the this pointer has type const B *. That's all there is to it. No more, no less. The effect of this is not different from what you would see in C language, for example. It makes pointer this->a const, but it doesn't affect the pointee.

实际上,由您决定是否将 B 的常数传播到 this-> a 指向的 A 对象.语言使您可以完全自由地做出此决定.它被称为概念上的恒定性"(与物理上的恒定性"或逻辑上的恒定性"相对).编译器仅观察和强制执行逻辑常数,而OOP中关键字 const 的目的远不止于此:它允许您在设计中实现概念常数的思想.

In fact it is up to you to decide whether the constness of B propagates to the A object pointed by this->a. The language gives you full freedom in making this decision. It is called "conceptual constness" (as opposed to "physical constness" or "logical constness"). The compiler observes and enforces only logical constness, while the purpose of keyword const in OOP goes far beyond that: it allows you to implement the idea of conceptual constness in your design.

如果将 A 对象视为 B 的组成部分,则 B 的恒定性也应表示 A的恒定性.但这是您必须手动观察和强制执行的操作(或者某些智能指针类可以帮助您完成此操作).

If the A object is considered an integral part of B, then the constness of B should also mean constness of A. But this is something you have to observe and enforce manually (or some smart pointer class can help you with this).

如果 A 对象是一个独立的对象,而恰好只是 B 引用,则 B 不一定暗示 A 的恒定性.

If A object is an independent object which just happens to be merely referenced from B, then constness of B should not necessarily imply constness of A.

编译器不会对此做出任何决定,因为编译器不知道您要实现哪种对象关系.在您的设计中,按照我的看法, A 对象实际上是 B 的组成部分,这意味着您不应该声明 to_upper作为 const .这是一个修改功能.它更改了用户认为的 B 的值.通过将 to_upper 声明为 const ,您实际上是在向用户撒谎".

The compiler does not impose any decisions on you with respect to this, since compiler has no idea what object relationship you are trying to implement. In your design, the way I see it, the A object is actually an integral part of B, which means that you weren't supposed to declare your to_upper as const. It is a modifying function. It changes what is perceived by the user as the value of B. By declaring to_upper as const you are essentially "lying" to the user.

这篇关于在const方法中修改Pointee值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆