1

Can you explain these lines?

class HasPtr {
public:
    HasPtr(const std::string &s = std::string())://this line
    ps(new std::string(s)), i(0) { } //and this

    HasPtr(const HasPtr &p):
    ps(new std::string(*p.ps)), i(p.i) { }

    HasPtr& operator=(const HasPtr &);

    ~HasPtr() { delete ps; }

private:
    std::string *ps;
    int  i;
};

This topic in book is about classes that act like values.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Konstantin
  • 111
  • 1
  • 8

2 Answers2

3

In this declaration of a constructor

HasPtr(const std::string &s = std::string())://this line
ps(new std::string(s)), i(0) { }

there is used the default argument std::string() and the mem-initializer list

ps(new std::string(s)), i(0)

that is executed before the control will be passed to the constructor body. As there is nothing to do in the body the body of the constructor is empty.

So you can call the constructor without an argument like

HasPtr obj;

in this case an empty string created like string() will be used as an argument.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

const std::string &s is a reference to a const instance of std::string.

= std::string() is a default value. xyz() is a syntax for a value-initialized instance of xyz.

So when HasPtr is instantiated without an argument (e.g. HasPtr()), the HasPtr(s) constructor will be invoked with s bound to a temporary blank std::string instance (which lives until the end of the full-expression, usually the first ;).

Then ps will be initialized with new std::string(s), making a copy of s on the heap and storing a pointer to it in ps.

If HasPtr is invoked with an actual argument, the = std::string() part will not execute.

rustyx
  • 80,671
  • 25
  • 200
  • 267