Toward the end of Chapter 16 of the "C++ Primer" I encountered the following code (I've removed a bunch of lines):
class Sales_item {
public:
// default constructor: unbound handle
Sales_item(): h() { }
private:
Handle<Item_base> h; // use-counted handle
};
My problem is with the Sales_item(): h() { }
line.
For the sake of completeness, let me also quote the parts of the Handle class template that I think are relevant to my question (I think I don't need to show the Item_base class):
template <class T> class Handle {
public:
// unbound handle
Handle(T *p = 0): ptr(p), use(new size_t(1)) { }
private:
T* ptr; // shared object
size_t *use; // count of how many Handles point to *ptr
};
I would have expected something like either:
a) Sales_item(): h(0) { }
which is a convention the authors have used repeatedly in earlier chapters, or
b) Handle<Item_base>()
if the intention was to invoke the default constructor of the Handle class.
Instead, what the book has is Sales_item(): h() { }
. My gut reaction is that this is a typo, since h() looks suspiciously similar to a function declaration. On the other hand, I just tried compiling under g++ and running the example code that uses this class and it seems to be working correctly. Any thoughts?
EDIT: All good answers, thanks! I have in the intervening 30 minutes tracked down a relevant quote from chapter 12 of the same book: "When we initialize a member of class type, we are specifying arguments to be passed to one of the constructors of that member's type. We can use any of that type's constructors." And as you all pointed out, in this case we are passing zero arguments.
What you have with Sales_item(): h() { }
is a constructor with a data member initialization.
I would have expected something like either:
a)
Sales_item(): h(0) { }
which is a convention the authors have used repeatedly in earlier chapters, or
This isn't necessary because the constructor of Handle<Item_base>()
can be invoked without an argument. (Its one argument has a default value, so it can be omitted.)
b)
Handle<Item_base>()
if the intention was to invoke the default constructor of the Handle class.
This is simply incorrect syntax. That syntax is used for base classes and there it is fine, since any class can inherit only once from Handle<Item_base>()
. However, it can have many data elements of that type, so in order to initialize the right data member, its name is used rather than its type.
That's a very good book you're learning from, BTW. Once you're through it, you might want to look at The Definitive C++ Guide and List for more good input.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With