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.

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)

Is something like this safe? I'm using 'const char*' instead of 'std::string' right now, is that safe?

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.

有帮助吗?

解决方案

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. If you are computing the string, then you can use static std::string const wrapped in a getter function.

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. The Base may store a string const & or a char const *, it doesn't really matter. I would recommend char const * because the string reference could potentially be accidentally initialized with a temporary.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top