c++ - 从 const 对象访问非常量方法

标签 c++ inheritance constants

我有一个 C++ 示例,我尝试在类成员上设置一个属性,该属性可通过 const getter 访问。

#include <iostream>

struct prop
{
    prop() : m_val {0} {}
    int val() const { return m_val; }
    void set_val(int v) { m_val = v; }
private:
    int m_val;
};

struct base
{
    virtual ~base() = default;
    virtual prop property() const = 0;
    virtual void set_property(prop p) = 0;
};

struct derived : public base
{
    derived() : m_prop {prop {}} {}
    prop property() const { return m_prop; }
    void set_property(prop p) { m_prop = p; }
private:
    prop m_prop;
};

int main()
{
    base *d1 = new derived();
    d1->property().set_val(2);
    // prints 0
    std::cout << "property val: " << d1->property().val() << '\n';
    delete d1;

    base *d2 = new derived();
    auto p = d2->property();
    p.set_val(2);
    d2->set_property(p);
    // prints 2
    std::cout << "property val: " << d2->property().val() << '\n';
    delete d2;

    return 0;
}

我希望这会给我带来 d1->property().set_val(2); 错误,因为 property() 方法是 const 并且应该给我一个没有 set_val 方法的 const prop 对象。但是编译时没有任何错误,并且 d1->property().set_val(2); 行实际上并没有更改 val,如 cout 所示 行。有人可以解释一下我缺少什么吗?

编辑:我现在了解 property() 返回非常量和按值的问题,以及为什么它不会给出编译器错误并且不会更改d1。我的用例中的最佳解决方案是将 property 的返回值设置为 prop const&

最佳答案

d1->property().set_val(2); doesn't actually change the val

因为 property() 按值返回,这意味着 property() 返回的是从数据成员 m_prop 复制的临时对象>。然后对临时对象调用 set_val 并立即销毁。

because property() method is const and should give me a const prop object

没有。您将返回类型声明为 prop,那么它将返回一个非常量 prop。在constproperty()中,数据成员m_prop变成const,它被复制到返回的对象中非常量。返回类型不会变成const

我认为您应该将返回类型更改为const prop&(在base衍生类中)。然后你会得到预期的错误。例如

const prop& property() const { return m_prop; }

关于c++ - 从 const 对象访问非常量方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59055394/

相关文章:

c++ - 未解析的外部符号

c++ - 结构成员(函数)可以在结构本身之前定义吗?

Java 继承错误 : Implicit Super Constructor is undefined

C++ 在方法中传递 const 字符串引用?

c++ - 什么是左值?

C++ typedef 与未详细说明的继承

ruby - 在模块中包含外部 Ruby 模块?

C++: protected 类构造函数

java - java中的常量含义

c++ - C++ 运算符重载返回中的常量正确性