1
votes

I read this from A tour of C++,

"Unlike an ordinary function, a constructor is guaranteed to be used to initialize objects of its class. Thus, defining a constructor eliminates the problem of uninitialized variables for a class."

How does this initialization work? E.g., suppose that I have a class with a field "s" of type string

class C{   
     std::string s;   
     ...

}

How does "s" get initialized, and would its value be guaranteed to be the empty string whatever the compiler?

2
What book are you using? This should be covered in a good C++ bookNathanOliver
Note that there are plenty of on-line material about this topic, e.g. en.cppreference.com/w/cpp/language/initializer_list or en.cppreference.com/w/cpp/language/default_constructorBob__
@Bob__ You should change your display name to __Bob, which would make your behavior undefined ;-)Daniel Langr
@DanielsaysreinstateMonica Well, that's what I was trying to avoid, unsuccessfully I'm afraid ;)Bob__
@2785528 the default ctor provided does nothing — It doesn't do nothing. The compiler-provided default constructor default-constructs all subobjects, including s.Daniel Langr

2 Answers

4
votes

The passage means that, if you have an Initialise() function, someone might forget to call it. It is not "guaranteed to be used", because you cannot control people. On the other hand, you cannot "forget" to call a constructor, because you never call a constructor: the computer does that for you when you instantiate your object.

Of course, that doesn't mean that the constructor is guaranteed to be properly written; that's still down to you. In the case of a class like std::string, though, it's pretty hard to get that wrong as it'll at least be default-constructed if you do not write code to do something else instead.

That happens whether or not you have an Initialise() function that's supposed to be called later, but if you did put some more complex initialisation in your constructor then you can be assured that this code will run.

// Bad! People can forget to call Initialise, so the string might stay empty
class Foo
{
public:
    void Initialise(const bool yesOrNo)
    {
        m_string = (yesOrNo ? "Yes!" : "No");
    }

private:
    std::string m_string;
};

// Good! You'll always have a value; no way around that
class Bar
{
public:
    Bar(const bool yesOrNo)
       : m_string(yesOrNo ? "Yes!" : "No")
    {}

private:
    std::string m_string;
};

Further reading:

1
votes

When your instance of C is made, the std::string s is initialized in what is known as Member initialization.

How does "s" get initialized, and would its value be guaranteed to be the empty string whatever the compiler?

You're not showing us how you create C, so we don't know what constructor is used. If the default constructor is used, then the default constructor of std::string is used for s. This does indeed make an empty string, as explained here:

Default constructor. Constructs empty string (zero size and unspecified capacity).