user1787379
user1787379

Reputation: 131

Self-returning class?

I was wondering if (in C++) you can instantiate a class (class foo) then have said class return the already instantiated object. (foo::instance())

In other words, can I have a class return it's-self via it's own methods? I want to be able to create a class (i.e. class foo) early in my program so it is already setup and ready to go. Then, farther down the line, I want to be able to call functions from that class without having to pass that object as an argument to my calling function. Can I do something like so: MyClass::ReturnSelf()->foo(); or MyClass::ReturnSelf().foo();

EDIT: I just realized this might be a little unclear. I want to be able to have another class call this "self-returning" method so it can use the already instantiated object's methods and members without creating a new object.

Upvotes: 2

Views: 6871

Answers (3)

rhavin
rhavin

Reputation: 1689

I just realized this might be a little unclear. I want to be able to have another class call this "self-returning" method so it can use the already instantiated object's methods and members without creating a new object.

define a class-variable in class foo of type foo that you can return in static class method instance(). You may also try to give it type *foo and set it up with a pointer on first ctor, wich makes it possible to derive from your class.

class Foo
{
   # class variable pointing to first instance
   static foo* pFoo = null;

   # constructor, sets pointer to first instance 
   Foo()
   {
      if (!pFoo) pFoo = this;
      /* ... */
   }

   # static class method returning instance
   static foo* instance() {return pFoo;}
}

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 476950

A static member function usually does the trick:

struct Foo
{
    static Foo & special_instance()
    {
        static Foo impl;  // Alarm bells: This is a global state!
        return impl;
    }

    // ...
};

Usage (from anywhere in the code):

Foo & f = Foo::special_instance();
// ...

You have the additional option of making all the constructors of the class private so that this sort of object creation is the only option. This is generally awkward design, but there may be situations where it is useful. Just be mindful whether you're modeling your problem correctly or whether you might get away with something simpler.

Upvotes: 0

Luchian Grigore
Luchian Grigore

Reputation: 258558

Congrats, you've discovered the singleton pattern. Quite a caveat, if you didn't already know it.

struct X
{
   static X& instance()
   {
       static X x;
       return x;
   }

   void foo();
};

and call the method as:

X::instance().foo();

Of course, you could also make the method static, if that's an option, and call it directly:

X::foo(); //this requires foo to be declared static

The effect of returning the instance from methods can also be used for method chaining:

struct Element
{
    Element& setColor() { return *this; }
    Element& setWidth() { return *this; }
};

Element e;
e.setColor().setWidth();

Upvotes: 7

Related Questions