简体   繁体   English

编译时间字符串分配以进行运行时识别

[英]Compile time string assignment for run-time identification

I've been using a pattern in a library I'm creating that uses passes a String name of an object to its base object's constructor. 我一直在使用创建的库中使用的模式,该模式使用将对象的字符串名称传递给其基础对象的构造函数。 I've tried using std::string and c-style strings but keep getting weird memory errors with Valgrind. 我试过使用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;
}

(This compiles and runs fine in Valgrind) (这可以在Valgrind中编译并正常运行)

Is something like this safe? 这样安全吗? I'm using 'const char*' instead of 'std::string' right now, is that safe? 我现在使用的是'const char *'而不是'std :: string',这样安全吗?

Is there a safer alternative, preferably without using virtuals? 有没有更安全的替代方法,最好不使用虚拟机?

Edit: Is there a way to do this with templates? 编辑:有没有办法用模板做到这一点? I don't want to use RTTI since it has the name mangled and I want the name to be 'normal' for use with scripting/data persistance. 我不想使用RTTI,因为它的名称被修改了,并且我希望该名称对于脚本/数据持久化来说是“正常的”。

Everything you do here is fine. 您在这里所做的一切都很好。

Templates would get you nothing because you still need to store a runtime pointer in the base class for dynamic identification. 模板将无济于事,因为您仍需要在基类中存储运行时指针以进行动态标识。

Smart pointers would get you nothing because the lifetime of the string is the entire program. 智能指针不会给您任何好处,因为字符串的生命周期就是整个程序。 If you aren't computing anything, char const * and initialization from a string literal are ideal. 如果您不进行任何计算,那么char const *和字符串文字的初始化都是理想的选择。 If you are computing the string, then you can use static std::string const wrapped in a getter function. 如果要计算字符串,则可以使用包装在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;
    }
};

This avoids the static initialization order fiasco. 这避免了静态初始化顺序的惨败。 (The getter function receives an extra multithreading-safe guard from the compiler.) The lifetime of the string is the lifetime of the program. (getter函数从编译器获得额外的多线程安全防护。) string的生存期就是程序的生存期。 The Base may store a string const & or a char const * , it doesn't really matter. Base可以存储string const &char const * ,这并不重要。 I would recommend char const * because the string reference could potentially be accidentally initialized with a temporary. 我建议使用char const *因为string引用可能会被临时性意外初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM