我有一个 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 theval
因为 property()
按值返回,这意味着 property()
返回的是从数据成员 m_prop
复制的临时对象>。然后对临时对象调用 set_val
并立即销毁。
because
property()
method isconst
and should give me aconst prop
object
没有。您将返回类型声明为 prop
,那么它将返回一个非常量 prop
。在const
property()
中,数据成员m_prop
变成const
,它被复制到返回的对象中非常量。返回类型不会变成为const
。
我认为您应该将返回类型更改为const prop&
(在base
和衍生
类中)。然后你会得到预期的错误。例如
const prop& property() const { return m_prop; }
关于c++ - 从 const 对象访问非常量方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59055394/