In Meyers Effective C++ item 31 (p147 in my 3rd edition) he talks about interface classes. He shows an example of a Person class with pure virtual methods and a derived class RealPerson. It looks something like this, though I've simplified it and added trivial implementations.
#include <string>
class Person {
public:
virtual ~Person() {};
virtual std::string name() const = 0;
};
class RealPerson : public Person {
public:
RealPerson(const std::string& name) : theName(name) {}
virtual ~RealPerson() {};
virtual std::string name() const { return theName; }
private:
std::string theName;
};
He then goes on to say that we can easily create a 'factory function' to create real people:
std::shared_ptr<Person>Person::create(const std::string& name) // EDIT - removed tr1::
{
return std::shared_ptr<Person>(new RealPerson(name));
}
Why would I want to use this 'create' function when I can just instantiate the RealPerson class in the normal way?
Also, why are the derived class methods 'virtual'.
Thanks for the comments. I understand the purpose (now) but I don't see how that differs from any base class in any hierarchy - are such factory functions typical in all base classes? It also has the feel of something of a kludge, not part of a language. But I am relatively new to C++ so that might just be my problem.
And keeping that logic in just one place to make it maintainable (OO+procedural dude!!)
If you've got a database or data entry screen that can store or allow entry of more than one person, when you want to write a function to read the screen to create the new person object, or, load the record from the database, the first line can't be 'new RealPerson(name);'. The data entry screen or database record might be talking about 'ImaginaryFriend(name)'. This would be given away by, in the simplest cases, a dropdown on the screen or a code/string in a column on the database.
And you can't create 'new Person' - it's virtual.
So before you start loading the fields or database columns into your new object, you make the new one by calling the factory and passing it a 'code' (or other 'giveaway' to what the object is that is consistent), which, in the most basic situation, will be examined by the factory (say by a simple switch statement) to figure out which 'new' to call. This way, your program isn't littered with switch statements to make the right kind of concrete object.
Of course, it can get way more complicated than that. This is just a situation that, if you do use inheritance, you will have to deal with when building the right subclass.
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