我在弄清楚const在特定情况下如何应用时遇到了一些麻烦。这是我的代码:

struct Widget
{
    Widget():x(0), y(0), z(0){}

    int x, y, z;
};

struct WidgetHolder //Just a simple struct to hold four Widgets.
{
    WidgetHolder(Widget a, Widget b, Widget c, Widget d): A(a), B(b), C(c), D(d){}

    Widget& A;
    Widget& B;
    Widget& C;
    Widget& D;
};

class Test //This class uses four widgets internally, and must provide access to them externally.
{
    public:
        const WidgetHolder AccessWidgets() const
        {
            //This should return our four widgets, but I don't want anyone messing with them.
            return WidgetHolder(A, B, C, D);
        }

        WidgetHolder AccessWidgets()
        {
            //This should return our four widgets, I don't care if they get changed.
            return WidgetHolder(A, B, C, D);
        }

    private:
        Widget A, B, C, D;
};

int main()
{
    const Test unchangeable;

    unchangeable.AccessWidgets().A.x = 1; //Why does this compile, shouldn't the Widget& be const?
}

基本上,我有一类叫做测试。它在内部使用了四个小部件,我需要它来返回它们,但是如果test被声明为const,我也希望小部件也返回const。

有人可以向我解释为什么main()中的代码可以编译吗?

非常感谢你。

最佳答案

之所以进行编译,是因为尽管WidgetHolder是const对象,但这种恒定性不会自动应用于指向WidgetHolder(由WidgetHolder指向)的对象。在机器级别上考虑一下-如果WidgetHolder对象本身保存在只读内存中,您仍然可以写入WidgetHolder指向的内容。

问题似乎在于此行:

WidgetHolder(Widget a, Widget b, Widget c, Widget d): A(a), B(b), C(c), D(d){}

如Frank所言,在构造函数返回后,WidgetHolder类中的引用将保存无效的引用。因此,您应该将其更改为:
WidgetHolder(Widget &a, Widget &b, Widget &c, Widget &d): A(a), B(b), C(c), D(d){}

完成此操作后,它将无法编译,我将其留给读者练习其余的解决方案。

07-26 05:55