c++ - 我可以从 std::string 继承以提供强类型字符串吗?

标签 c++ templates inheritance stdstring strong-typedef

在我正在处理的代码库中,大多数函数都将几个 std::string 作为参数。这些字符串代表不同的东西,如果可能的话,我想定义几个类来在编译时检测不一致。

这是一个有问题的代码示例:

void displayIdentity(const std::string &firstName, const std::string &lastName) {
    std::cout << "First name = " << firstName << "\t; " << "Last name = " << lastName << std::endl;
}

const std::string firstName = "John";
const std::string lastName  = "Doe";
displayIdentity(lastName, firstName); // clearly, it should have been 
                                      // displayIdentity(firstName, lastName)

我目前使用的解决方案是使用使用模板定义的不同类:

template <typename NAME> class TypedString : public std::string {
  public:
    explicit TypedString(const char* s) : std::string{s} {}
  
    explicit TypedString(const std::string& s) : std::string{s} {}
};

然后就可以在编译时检测不一致了:

const FirstName firstName2{"John"};
const LastName  lastName2{"Doe"};
displayIdentity2(firstName2, lastName2);
// displayIdentity2(lastName2,  firstName2); // error: invalid initialization of reference of type 
                                             // 'const FirstName&' from expression of type 'LastName'
    
    
//const LastName lastName3{firstName2};      // error: invalid initialization, as expected

const LastName lastName3{std::string(firstName2)}; // but conversion can to requested explicitly 
    

我已经开始使用这段代码,它按预期工作并帮助我检测不一致。

我已阅读 on this post我们不应该从 std::string 继承,因为它的析构函数不是虚拟的。

由于 TypedString 类是空的,它的析构函数应该等同于 std::string 析构函数,所以我不认为这是问题。方法也一样,我不关心在使用多态性时是否调用了 std::string 方法,因为我希望 TypedString 的行为与字符串完全一样,除了构造/转换...

我说的对吗?或者我应该使用更详细的解决方案(使用组合 as done here )来解决我的问题?

最佳答案

只要您不通过指向 std::string 的指针删除您的 TypedString 的任何实例 virtual 析构函数是无关紧要的。

也就是说,以下行为是未定义的,因为 std::string 的析构函数不是 virtual:

std::string* name = new FirstName{"John"};
delete name;

如果您从不以这种方式使用您的类(class),您就不会有任何问题。使用私有(private)继承并显式公开您需要的成员函数可能是值得的。这会完全阻止上面的代码片段编译,但它也可能使显式所需的转换更加困难或冗长。

关于c++ - 我可以从 std::string 继承以提供强类型字符串吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74375231/

相关文章:

c++ - 如何在不使用宏的情况下在宏中创建条件

c++ - 怎样让白色变透明

c++ - 常量做什么?

c++ - 检查某种类型是否是模板类 std::optional 的实例化

通过可变模板继承 C++11 构造函数

c++ - Visual Studio 2010- fatal error LNK1120 : 1 unresolved externals; c++

c++ - 有条件地禁用复制构造函数

c++ - 如何从 Eigen::MatrixBase<Derived> 获取存储选项

C# 泛型转换

c++ - 为什么范围解析不适用于重写变量?