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

C++中是否需用final修饰set_height防止重写?附编译影响疑问

问题:是否需要将set_height标记为virtual...final?

假设我有一个类,其封装变量需要进行条件保护,示例代码如下:

class person {

private:
    int height_;

public:
    explicit person(int height) {
        this->height_ = height;
    }

    int get_height() const noexcept {
        return height_;
    }

    void set_height(int height) {
        if (height < 0)
            throw std::invalid_argument("Height cannot be negative");
        this->height_ = height;
    }
};

我知道可以将height设为unsigned int,但这只是众多可能问题场景的示例。请问是否需要将set_height标记为virtual...final以防止派生类重写?还是默认假设正常情况下不会出现此类重写?另外,这么做会增加编译时间或存在其他负面影响吗?


回答

核心判断:看你的类设计意图

如果你的person类不打算作为基类被继承,那完全没必要加virtual...final——直接把整个类标记为final更干脆,从根源上禁止继承,也就不存在重写的问题了。

如果你的类允许被继承,但必须保证set_height的校验逻辑不被破坏,那一定要给set_height加上final(不需要额外加virtual,除非你原本就打算让它成为虚函数)。因为一旦派生类重写了set_height,很可能会绕过你写的合法性校验,导致height_被设置为非法值,直接破坏类的封装不变式(invariants)。

别依赖“默认假设”

别寄希望于“正常情况下不会重写”——代码维护过程中,后续接手的开发者可能会出于各种原因去重写这个方法。如果校验逻辑是类的核心约束,就必须用代码强制执行,而不是靠口头约定。

负面影响几乎可以忽略

  • 编译时间:加final对编译速度的影响微乎其微,甚至可能因为编译器能做更多优化(比如非虚函数的静态绑定),反而让编译或运行效率更高。
  • 运行时开销:final只是一个编译期标记,不会带来任何运行时性能损耗。唯一的小局限是如果后续真的需要修改设计允许重写,得去掉final,但这种情况在设计明确的前提下很少发生。

额外优化建议

如果你的类允许继承,但希望派生类能扩展校验逻辑而不是完全替换,可以把校验逻辑抽成私有辅助函数,同时补上构造函数的校验漏洞:

class person {
private:
    int height_;
    void validate_height(int height) {
        if (height < 0)
            throw std::invalid_argument("Height cannot be negative");
    }
public:
    explicit person(int height) : height_(height) {
        validate_height(height); // 构造时也要校验,避免对象初始状态非法
    }

    int get_height() const noexcept {
        return height_;
    }

    virtual void set_height(int height) {
        validate_height(height);
        height_ = height;
    }
};

这样派生类重写时,只要调用validate_height就能保证基础校验不被跳过,同时可以添加自己的逻辑:

class adult : public person {
public:
    void set_height(int height) override {
        validate_height(height); // 保留基础校验
        if (height > 250)
            throw std::invalid_argument("Adult height cannot exceed 250cm");
        person::set_height(height);
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:21:17