键入安全字符串参数

Type-safe string parameters

本文关键字:参数 字符串 安全      更新时间:2023-10-16

我的库以字符串的形式从消息总线获取信息。这些字符串是需要处理的不同类型实体的标识符。

目前的方法可能是这样的:

void doWork(const std::string& carModelId,
            const std::string& dealershipId,
            const std::string& invoiceId);
float getPrice(const std::string& carModelId, 
               const std::string& dealershipId);

由于这些不同类型的id到处都在使用,我希望确保将正确类型的id传递给方法,而不是使用纯字符串。

我目前的想法是创建一些结构来包装这些字符串

struct carModel
{
     std::string id;
}

以便这些方法只接受正确类型的id

void doWork(const carModel& carModelId,
            const dealership& dealershipId,
            const invoice& invoiceId);

另一方面,这似乎是一个常见问题的许多额外样板代码。

问题:获得字符串参数的类型安全性的最佳实践是什么?

最佳实践实际上取决于您的软件、环境、IDE、编译器等等。

在这个特定的场景中,我认为绝对没有问题

struct SomeId {
    std::string id;
}

只要您在整个应用程序中保持所有的一致性。您可以获得的主要优势,以后您可以使用其他行为自定义这些结构(获取id的用法,在不同数据类型之间进行转换,为调试目的获得漂亮的打印名称,跟踪应用程序中使用的id,等等)。这很好,因为发生的一切对类的用户来说都是透明的。

此外,这些类型的结构可以自动进行额外的验证(这个id有效吗?它已经可用吗?应该是)。您需要这些东西的程度以及它们是否真的可行取决于您的应用程序的逻辑。

你应该始终保持简单明了,在这种情况下,你实际做的事情非常符合问题描述。不要使事情过于复杂。

但是,有一个建议:在这种情况下,请远离显式转换运算符等。您应该阻止编译以下代码。

SomeId id = someOtherIdType;

您可以使用一些技巧,例如使用operator()operator->作为语法糖,但这是我所能做到的。

实现一次并在任何地方使用,你可以在像这样的基类中拥有所有东西

struct BaseId
{
    std::string id;
    void Do() { }
    //add common behavior to all id classes
    //...
};
struct myId : private BaseId
{
    using BaseId::id;
};

私有继承允许派生类控制公开什么和不公开什么,并防止不同id类之间的类型兼容性。

在基类中,您可以记录、处理、提供其他方法等等。实现运算符重载也可以在基类中完成。

你的身份证需要它吗?我不知道。可能有些过头了,可能不会。但考虑这些选择是值得的。正如我早些时候所说的,采用在您的情况下运行良好的简单方法(即使是一些typedef也可能足够,如果不是,结构也会表现良好)。