2
class Investment { ... }; // root class of hierarchy of
                          // investment types

Investment* createInvestment(); // return ptr to dynamically allocated
                                // object in the Investment hierarchy;
                                // the caller must delete it
                                // (parameters omitted for simplicity)

void f()
{
Investment *pInv = createInvestment(); // call factory function
...                                    // use pInv
delete pInv;                           // release object
}

In the book, the author gives the example code like the one shown above. This is the first time I've seen this line:

Investment* createInvestment(); // call factory function

Is this function written inside the class definition or outside? What are the requirements in the class definition to make that line functional? i.e. Would you need a definition like this? Is this even a valid definition?

class Investment {
    public:
        Investment* createInvestment(){
            return ptr;
        };
    private:
        Investment* ptr;
};
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
niamleeson
  • 189
  • 1
  • 3
  • 10
  • [This](http://stackoverflow.com/questions/5120768/how-to-implement-the-factory-method-pattern-in-c-correctly) may be helpful. – jcai Aug 29 '15 at 04:13
  • Thank you for that article. So do you always create a new object inside the factory function? – niamleeson Aug 29 '15 at 04:33
  • `class Investment { ... }; Investment* createInvestment();` – seriously, it should be pretty clear that the function is **not** a member of the `Investment` class. – The Paramagnetic Croissant Aug 29 '15 at 05:13
  • @niamleeson a factory function typically creates a new object and relinquishes ownership of the created object to the caller, yes. In other circumstances you could have a class that owns objects and returns non-owning pointers or references to those owned objects but I wouldn't call that a factory. – Chris Drew Aug 29 '15 at 07:05

2 Answers2

3

Is this function written inside the class definition or outside?

It can be either. In this example it's outside the class in a free function. It could also be put inside a separate InvestmentFactory class. But it could also be put inside the Investment class, in which case it would need to be static (i.e. not tied to a specific Investment).

What are the requirements in the class definition to make that line functional?

If the constructor of Investment is accessible from inside createInvestment (in this case, it would have to be public), then it could be as simple as

Investment* createInvestment() { return new Investment; }

But in your example there is a comment that Investment is the "root class of hierarchy of investment types". That means that the createInvestment method probably exists to create classes derived from Investment, and return an Investment* to allow for polymorphism. For example suppose Stock and Bond both derive from Investment; then createInvestment might look like this:

Investment* createInvestment(InvestmentType investType) {
    switch (investType) {
        case STOCK:
            return new Stock;
        case BOND:
            return new Bond;
        default:
            throw std::invalid_argument("investType");
    }
}

It's a rather silly example, but it just shows something that could work.

In your example:

class Investment {
    public:
        Investment* createInvestment(){
            return ptr;
        };
    private:
        Investment* ptr;
};

This is very wrong (although it will compile). First of all, there is no need for a class to store a pointer to itself (that's the this keyword). Second, you never initialize ptr, so your createInvestment will return an uninitialized pointer. You need a new somewhere to actually create an object.

jcai
  • 3,448
  • 3
  • 21
  • 36
2

The factory function is a non-member function. I would expect it to take a parameter that specifies the type of Investment to create:

Investment* createInvestment(const std::string& type, int amount) {
    if(type == "stock") 
        return new Stock(amount);
    else
        return new Bond(amount);
} 

where Stock and Bond are classes which derive from Investment.

The calling code is taking ownership of the Investment and must remember to call delete on it. For this to work Investment must have a virtual destructor. It will probably have other virtual member functions to provide polymorphic behaviour and may be abstract.

class Investment {
public:
    virtual ~Investment(){}
    virtual int getAmount() const = 0;
};

The modern way of writing such a factory function is to return aunique_ptr:

std::unique_ptr<Investment> createInvestment(const std::string& type, int amount) {
    if(type == "stock") 
        return std::make_unique<Stock>(amount);
    else
        return std::make_unique<Bond>(amount);
}

Then you don't need to remember to call delete.

Live demo.

Chris Drew
  • 14,926
  • 3
  • 34
  • 54
  • Thank you for your reply. I do have one more question; if you create a new object inside `createInvestment()`, shouldn't you delete them later? How would you go back and delete them? – niamleeson Aug 29 '15 at 05:37
  • @niamleeson Yes, Scott says as much in his comment. But not if you use `unique_ptr`. I'll try and make it more clear in my answer... – Chris Drew Aug 29 '15 at 05:39
  • @niamleeson I'm not sure what you mean by "go back and delete them". If the calling code calls `delete` on the created `Investment` and it has a virtual destructor then the `Stock` or `Bond` will be properly destroyed. – Chris Drew Aug 29 '15 at 05:49