c++ - 编译时字符串赋值用于运行时识别

标签 c++ inheritance cstring stdstring compile-time

我一直在我正在创建的库中使用一种模式,该模式使用将对象的字符串名称传递给其基础对象的构造函数。我试过使用 std::string 和 c 风格的字符串,但在使用 Valgrind 时总是出现奇怪的内存错误。

class Base {
public:
    Base( std::string name ) : name(name) {}
    virtual ~Base() {}
    std::string getName() { return name; }
private:
    std::string name;
};

class Derived : public Base {
public:
    Derived() : Base("Derived") {}
};

int main() {
    Base* derived = new Derived;
    std::cout << derived->getName() << "\n";
    delete derived;
}

(这在 Valgrind 中编译和运行良好)

这样的东西安全吗?我现在使用的是“const char*”而不是“std::string”,这样安全吗?

是否有更安全的替代方案,最好不使用虚拟机?

编辑:有没有办法用模板做到这一点?我不想使用 RTTI,因为它的名称被破坏了,我希望名称是“正常的”以便与脚本/数据持久性一起使用。

最佳答案

你在这里做的一切都很好。

模板不会给你带来任何好处,因为你仍然需要在基类中存储一个运行时指针以进行动态识别。

智能指针不会给你带来任何好处,因为字符串的生命周期就是整个程序。如果您不计算任何内容,char const * 和从字符串文字进行初始化是理想的选择。如果要计算字符串,则可以使用包含在 getter 函数中的 static std::string const

class Derived : public Base {
public:
    Derived() : Base(get_name()) {}
private:
    static std::string const & get_name() {
        static std::string const name = "Derived"; // or = compute_name();
        return name;
    }
};

这避免了静态初始化顺序的失败。 (getter 函数从编译器接收额外的多线程安全防护。)string 的生命周期就是程序的生命周期。 Base 可能存储一个string const & 或一个char const *,这并不重要。我会推荐 char const *,因为 string 引用可能会被临时初始化。

关于c++ - 编译时字符串赋值用于运行时识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17777850/

相关文章:

C++ getpeername 返回 0.0.0.0 :0

C++ 对指向结构的 const 指针数组进行排序

c++ - 空基类优化

连接到 MySQL 数据库的 Python 脚本 - 代码作为程序脚本运行,在 OOP 重构后失败

c# - 如何正确包装 Dictionary<T,U> 并公开枚举器?

java - Java 和 Python 中继承的区别

ios - NSString 字符串与 CString :encoding: - not copying the Cstring?

C++ 通过访问器返回一个字符串

c++ - 将 CString 传递给 fprintf