CS253: Software Development with C++

Fall 2021

Default Methods

Show Lecture.DefaultMethods as a slide show.

CS253 Default Methods

 

a couple of poor default avatars

The word

The word “default” has several meanings in C++:

string s;  // no parens, but ctor still called
cout << s.size() << ' ' << s.capacity() << ' ' << sizeof(s);
0 15 32

Simple Example

class Foo {
  public:
    Foo(const string &n) : name(n) { }
    string name;
};

Foo a("Diane"), b(a);
cout << a.name << ' ' << b.name << '\n';
Diane Diane

There’s no copy ctor, so who set b.name to Diane?

Default Copy Ctor

class Foo {
  public:
    Foo(const string &n) : name(n) { }
    string name;
};

Foo a("Diane"), b(a);
cout << a.name << ' ' << b.name << '\n';
Diane Diane

There is a default copy ctor, which performs a bitwise copy on the object.

No

NO!

I Lied

Like this

The default (compiler-generated) copy ctor & assignment operators look like this:

class Foo {
  public:
    Foo(const string &n) : name(n) { }
    Foo(const Foo &rhs) : name(rhs.name) { }
    Foo &operator=(const Foo &rhs) {
        name = rhs.name;
        return *this;
    }
    string name;
};

Foo a("Diane"), b(a);
b = a;
cout << a.name << ' ' << b.name << '\n';
Diane Diane

Missing

class Foo {
  public:
    Foo() = default;                    // I love this one.
    Foo &Foo(const Foo &) = delete;     // Not wild about this one.
    ...
};

Inheritance

Great! That explains everything!

Wait—what about inheritance?

Inheritance Example

struct Base {   // struct ≡ public access
    string name;
};
struct Derived : public Base {
    Derived(const string &n) { name = n; }
};

Derived a("Dorothy"), b(a);
cout << a.name << ' ' << b.name << '\n';
Dorothy Dorothy

How did that work‽ Who copied name? Sure, the Base default copy ctor would copy name, but nobody called that.

Sure Did

Code with Default Methods

struct Base {   // struct ≡ public access
    Base() { }
    Base(const Base &rhs) : name(rhs.name) { }
    Base &operator=(const Base &rhs) {
        name = rhs.name;
        return *this;
    }
    string name;
};
struct Derived : public Base {
    Derived(const string &n) { name = n; }
    Derived(const Derived &rhs) : Base(rhs) { }
    Derived &operator=(const Derived &rhs) {
        Base::operator=(rhs);
        return *this;
    }
};

Derived a("Dorothy"), b(a);
cout << a.name << ' ' << b.name << '\n';
Dorothy Dorothy