You have at least two options:
1 Use pointers
That's the option you seem to want to go for with using NULL and stuff... if the person for the book is really optional, you can make a pointer (or even better, a shared_ptr or some other smart pointer) out of the person member to make it possible to have the state "person not set", e.g.
class Book {
string title;
std::shared_ptr<Person> person;
void getPerson(std::shared_ptr<Person> p) {
return person = p;
}
std::shared_ptr<Person> getPerson() {
return person;
}
};
You'll have to access members of that person with -> then though (e.g., let's assume person has a constructor taking the name, and a getName
function:) - of course you'll have to be careful to not dereference an unset pointer, just as well as with raw pointers (or with the references in Java, where to me it seems you might come from?).
Book b1;
// ... set Person ...
b1.setPerson(std::make_shared<Person>("John"));
Then you can check if person is set simply by checking the default bool operator of the std::shared_ptr, like this:
// somewhere in Book class:
if (person) ...
2 "Empty" convention
Make a convention for what it means for a person to be unset (e.g. that when the name is empty, it is the "default", i.e. unset person). Then you can simply check in Book class:
if (person.getName().empty()) ...
Notice however that with this option you're more likely to run into problems when your Person
class changes, as it is now tightly coupled into the Book
class. E.g. at some point you might require for the Person's name to actually be set on construction, you'd have to change your logic in Book as well.