You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需const_cast,如何让C++数据成员构造后变为const(含昂贵中间值场景)

问题:不依赖const_cast实现构造完成后变为const的数据成员

当存在计算成本高昂、需用于计算多个数据成员的中间值时,不依赖const_cast,如何让C++的数据成员在构造完成后而非构造期间变为const?

以下是一个最小化、完整可验证的示例,进一步解释问题及原因。建议先阅读示例中的两处注释以节省时间。

#include <iostream>

namespace {

    constexpr int initializer {3};
    constexpr int ka {10};
    constexpr int kb {25};

    class T {
    private:
        int value;
        const int a_;
        const int b_;
    public:
        T(int n);
        inline int operator()() const { return value; }
        inline int a() const { return a_; }
        inline int b() const { return b_; }
        int &operator--();
    };

    T::T(const int n): value {n - 1}, a_ {0}, b_ {0}
    {
        // The integer expensive
        //     + is to be computed only once and,
        //     + after the T object has been constructed,
        //       is not to be stored.
        // These requirements must be met without reliance
        // on the compiler's optimizer.
        const int expensive {n*n*n - 1};
        const_cast<int &>(a_) = ka*expensive;
        const_cast<int &>(b_) = kb*expensive;
    }

    int &T::operator--()
    {
        --value;
        // To alter a_ or b_ is forbidden.  Therefore, the compiler
        // must abort compilation if the next line is uncommented.
        //--a_; --b_;
        return value;
    }

}

int main()
{
    T t(initializer);
    std::cout << "before decrement, t() == " << t() << "\n";
    --t;
    std::cout << "after  decrement, t() == " << t() << "\n";
    std::cout << "t.a() == " << t.a() << "\n";
    std::cout << "t.b() == " << t.b() << "\n";
    return 0;
}

程序输出

before decrement, t() == 2
after  decrement, t() == 1
t.a() == 260
t.b() == 650

(我了解此前的一个入门级问题,但该问题仅涉及基础场景。请参考上述代码中的注释。我的诉求是:避免重复执行昂贵的初始化操作,不存储中间结果,同时让构造完成后的常量数据成员受编译器保护,且不使用const_cast、不浪费资源。我并非询问如何避免常量数据成员,而是探讨该场景下的实现方案。)

后续思考

在阅读答案并试验后,我认为自己方法有误。尽管C++支持const数据成员,但它们的使用常与常规数据范式相悖——可变对象的const成员并非真正意义上的常量,可通过父对象赋值覆盖,不符合预期用途。

@Homer512的评论指出问题:

Don't overstress yourself into making members const when it is inconvenient. If anything, it can lead to inefficient code generation, e.g. by making move-construction fall back to copy constructions.

防止无意修改的正确方式是不提供修改接口;若需保护成员不受类自身函数修改,@Some programmer dude的答案给出了实现方法。我现在怀疑C++中能否顺畅处理const数据成员,这种场景下const的保护对象并不恰当。

内容的提问来源于stack exchange,提问作者thb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:50:32