我一直在使用我正在创建的库中的模式,该模式使用将对象的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,因为它的名称已经损坏,我希望名称与脚本/数据持久性一样“正常”。
答案 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
引用可能会被临时意外初始化。