C++中含抽象父类的对象接收原始数据时的最优验证方案
问题描述
我需要接收用户输入的原始数据,并用其初始化一个带有抽象父类的类。如果在初始化前做校验,会把类的验证逻辑移出类外,导致代码重复或者重复执行。我试过好几种方案,但都不太理想,希望能得到最优解。
已考虑的方案
构造函数抛出异常
看似是最优方案,但在原始数据输入场景下,用异常控制程序流程并不推荐。实测在微控制器中抛出异常耗时61ms,这个开销完全无法接受。
对象有效性标志
如果类被频繁使用,会产生额外开销;而且必须在每个方法里检查对象有效性,还会限制返回值(比如用std::optional的话,调用处要频繁做检查)。
创建对象后校验,无效则删除
这个方案可行,但会增加对象创建的额外开销。
静态方法/建造者/工厂模式创建对象
目前暂时选了这个方案,但在包含抽象父类的场景下代码组织很复杂,核心问题是构造函数和setter的验证代码重复。为了减少重复,setter需要通过虚函数委托调用子类静态方法,子类静态方法则聚合抽象类的通用校验和子类专属校验逻辑。
#include <optional> class FavoriteNum { protected: int favorite; public: virtual int compute() const = 0; // Setter bool setFavorite(int i) { if (v_isFavoriteValidation(i)) { favorite = i; return true; } return false; }; protected: FavoriteNum(int i) :favorite(i) {}; virtual bool v_isFavoriteValidation(int i) = 0; // Сommon for children static bool biggerOrEqual(int newFavorite, int favorite) { return newFavorite >= favorite; } }; class Favorite2 : public FavoriteNum { protected: Favorite2(int i) :FavoriteNum(i) {}; static constexpr int default_favorite = 2; public: // Doesn't matter, some logic int compute() const override { return favorite * 2; }; // Builder, there could be a static function here, it doesn't matter what exactly class FavoriteBuilder { protected: int val; public: FavoriteBuilder& setVal(int i) { val = i; return *this; }; std::optional<Favorite2*> build() { if (isFavoriteValidation(val, default_favorite)) { return new Favorite2(val); } return std::nullopt; }; }; protected: // Virtual func for validation in setter, just delegate work bool v_isFavoriteValidation(int i) override { return isFavoriteValidation(i, favorite); } // Static func for validation in builder and aggregation of validation functions static bool isFavoriteValidation(int i, int curFavorite) { return biggerOrEqual(i, curFavorite) && isFavoriteNumber(i); } // Specific for class validation logic static bool isFavoriteNumber(int i) { return i % 6 == 0; } };
内容的提问来源于stack exchange,提问作者vet etv
相关产品推荐
相关产品推荐

