编译运行时标识的时间字符串分配

时间:2013-07-21 23:04:57

标签: c++ inheritance cstring stdstring compile-time

我一直在使用我正在创建的库中的模式,该模式使用将对象的String名称传递给其基础对象的构造函数。我尝试过使用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,因为它的名称已经损坏,我希望名称与脚本/数据持久性一样“正常”。

1 个答案:

答案 0 :(得分:0)

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

模板无需任何操作,因为您仍需要在基类中存储运行时指针以进行动态识别。

智能指针不会给你任何东西,因为字符串的生命周期是整个程序。如果你没有计算任何东西,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引用可能会被临时意外初始化。