在我正在处理的代码库中,大多数函数都将几个 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/