1

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

4

1 回答 1

0

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

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

智能指针不会给您带来任何好处,因为字符串的生命周期是整个程序。如果您不计算任何东西,那么char const *从字符串文字初始化是理想的。如果您正在计算字符串,那么您可以使用static std::string const包装在 getter 函数中。

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可能存储 astring const &或 a ,这char const *并不重要。我会推荐char const *,因为string引用可能会被临时初始化。

于 2013-07-21T23:35:57.683 回答