C++ 修改常量方法中的指针对象值

C++ 修改常量方法中的指针对象值,c++,constants,C++,Constants,请看这段非常简单的代码: 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

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

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());
}
结构A{char*s;}; B类 { A*A; public:B(const char*s):a(新的a()){ int len=strlen(s); a->s=新字符[len+1]; memcpy(a->s,s,len+1); } ~B(){delete[]a->s;delete a;} const char*c_str()const{return a->s;} 常数B和至上()常数{ char*x=a->s; int len=strlen(x); 对于(int i=0;i='a'&&k说你好(); 归还*这个; } }; int main(){ B B=“hola mundo”; printf(“%s\n”,b.to_upper().c_str()); } 我的问题是…为什么

to_upper()方法是const,并通过“a”修改值指针对象。好的,我无法执行类似“a=nullptr”的操作,因为编译器说:“您正在尝试修改只读对象”;但它允许我修改基础值。这种行为正确吗?是否应该将“a”类型转换为“const a*”与const方法中的“this”类型转换为“const B*”的方式相同


谢谢!

常量函数不能修改类成员。'a'的指针对象不是该类的成员。

方法的常量转换为
*这个
对象的常量,这意味着
中的
到上面的
这个
指针具有类型
常量B*
。这就是它的全部内容。没有更多,没有更多例如,它的效果和你在C语言中看到的没有什么不同。它使指针
this->a
const,但并不影响指针对象

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

如果
A
对象被视为
B
的一个组成部分,那么
B
的常量也应该意味着
A
的常量。但这是您必须手动观察和执行的(或者一些智能指针类可以帮助您)

如果
A
对象是一个独立的对象,恰好是从
B
引用的,那么
B
的常量不一定意味着
A
的常量


编译器不会就此对您施加任何决定,因为编译器不知道您试图实现的对象关系。在您的设计中,我认为,
A
对象实际上是
B
的一个组成部分,这意味着您不应该将
声明为
const
。它是一个修改函数。它更改用户认为
B
的值。通过将
声明为
const
实际上是在向用户“撒谎”。

您使用了错误的delete[]在
B
的dector中,这是正确的;我创建了一个字符数组。您没有修改
B
对象。您没有承诺不修改其他对象(由
a
指向的对象)。第一句可能重复的句子并不完全正确,因此此解释失败。
编译器只观察并强制执行物理常量
,这不应该是
编译器只观察并强制执行逻辑常量
?因为物理常量AFAIK谈到将对象放入只读内存中Jesse Good:我使用了一个稍微不同的术语,但我同意你的术语更有意义。我修改了答案。