2

How should I write a copy constructor for my singleton class to prevent the creation of a new object as I already have one . And what is the best practice to overload = operator for same

 #include <iostream>
 #include <stdio.h>
 #include <conio.h>

 using namespace std;

 class Rect
 { 
  int length;
  int breadth;
  static int count;
  static int maxcount;
  Rect()
  {};
  Rect(const Rect& abc){};
  public :

      ~Rect();
      int area_rect()          
      {return length*breadth;}
      void set_value(int a,int b);

      static Rect* instance()
      {     
            Rect* ptr=NULL;
            if(count < maxcount)
            {
              ptr=new Rect ;
              count++;
            }
             return ptr;
       }
     };
    int Rect::count = 0;
    int Rect::maxcount = 1;
    void Rect::set_value(int a,int b)
   {
    length=a;
    breadth=b;
   }
  Rect::~Rect()
  {
   count --;          
  }  
 int main()
 {
  Rect* a= Rect::instance();  //creates first object
  // Rect* c= Rect::instance();  //fails to create second object 
  //as maxcount=1 and returns NULL
  a->set_value(10,3);
 cout << "area realted to object a : "  << a->area_rect() <<"\n"; 
 Rect* b=a;//allows creation of second object which I dont want
 b->set_value(10,4);
 cout << "area realted to object b : "  << b->area_rect() <<"\n"; 
 delete a;
 delete b;
 getch();
 return 0;
}       

How to write copy constructor code and overloading equal operator for prevention of creation of further object?

Striezel
  • 3,693
  • 7
  • 23
  • 37
Invictus
  • 4,028
  • 10
  • 50
  • 80
  • 5
    I think "best practice" is not to have a singleton at all. Just don't make more than one if you don't want to have more than one. – Kerrek SB Jan 16 '12 at 16:54
  • @KerrekSB What someone else works on same application and is new to it and makes an another object and i dont want that to happen ? – Invictus Jan 16 '12 at 16:57
  • 1
    Rect* b=a; does not create a second object. "b" will be a pointer to "a" – Neox Jan 16 '12 at 16:58
  • @Neox Yeah i guess you are right this is a shallow copy and now b and a points to same place i checked by modifying the dude thanks a ton and also i tested by deleting after assigning it to a it does print the area finally but ultimately give a segmntation fault :) – Invictus Jan 16 '12 at 17:02
  • 2
    @Ritesh: Rethink and redesign. Why is it a problem if someone else makes an object? Just tell them to use your existing object. There's a difference between just *having* one object (perfectly fine, consider using a global variable) and *enforcing* that only one can be constructed. – Kerrek SB Jan 16 '12 at 17:23
  • @KerrekSB yeah you are right but i might not be always there to ask them to use just one object already defined .. Thanks a lot as always :) – Invictus Jan 16 '12 at 17:27
  • @Ritesh: You can make the object uncopyable, that's not a problem - but that's not the same as a singleton. Look at `std::cout`: Nobody worries that anyone might accidentally make a copy of that, but it's not a singleton. – Kerrek SB Jan 16 '12 at 17:29
  • 2
    @KerrekSB So is the entire concept of singleton more of a bullshit ? – Invictus Jan 16 '12 at 17:31
  • @Ritesh it has *some* uses, but keep the amount of singletons at a minimum. Don't make a class a singleton unless it's semantically correct to have only one instance of it in any possible program where that class would be usable. A singleton is simply a class that **can** only have one instance. –  Jan 16 '12 at 17:42
  • 3
    @Ritesh: Yes, Singletons are bovine excrements. http://jalf.dk/singleton/ – sbi Jan 16 '12 at 17:53
  • 2
    [Another article](http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx), and [another](http://www.ibm.com/developerworks/webservices/library/co-single/index.html), and [another](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons). – Kerrek SB Jan 16 '12 at 18:03
  • @sbi seems like my loathing for it has increased to same degree as jalf :) – Invictus Jan 16 '12 at 19:17
  • @WTP: Not only one instance of the class, but also a *globally accessible one*. It's the combination of "features" that makes singletons nigh-useless. – Xeo Jan 16 '12 at 19:32
  • @all I always thought singleton was fascinating ...but now feels otherwise :) – Invictus Jan 16 '12 at 19:35

3 Answers3

10

Either you make it non-copyable as explained here

How do I make this C++ object non-copyable?

or you define the copy constructor and assignment operators such that you get the same singleton. Depending on the functionality you actually want.

Assignment should typically also be forbidden (as on the link above):

class Rect{
     Rect( const Rect& ) = delete;
     Rect& operator=( const Rect& ) = delete;
     . . .
}

This also forbids move operations.

You may also want to know this: Are Singletons really that bad?

Community
  • 1
  • 1
Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
7

Singletons are ridiculous, just use free functions.

Still, to answer your question...

C++11:

class Foo {
public:
    Foo (const Foo &) = delete;
    Foo & operator = (const Foo &) = delete;
};

C++03;

class Foo {
private:
    // Don't write bodies.
    Foo (const Foo &);
    Foo & operator = (const Foo &);
};
spraff
  • 32,570
  • 22
  • 121
  • 229
0

Here is related answer : if you don't want someone to create an object, don't give them public constructor!

Seriously, you can have a factory object, make it a friend to class which you want to restrict construction of, and make constructor of that class private. This way the only way to access an object (without even necessarily creating it at this time) would be through your factory.

e.g.

#include <boost/noncopyable.hpp>
#include <string>

class ConnectionFactory;

class DatabaseConnection : boost::noncopyable {
  // can only be created by ConnectionFactory which happens to 
  // know how to connect to our database server!
  friend class ConnectionFactory;
  DatabaseConnection(std::string username, std::string password /*etc*/);
  // don't want any random user to reset the connection!
  ~DatabaseConnection();

public:
  // public interface bits
  void Execute(const Select&);
  // ...
};

ConnectionFactory {
public:
  DatabaseConnection& conn();
};

class MayNeedDbConnection {
  ConnectionFactory factory;
public:
  explicit MayNeedDbConnection(const ConnectionFactory& f) : factory(f)
  {}

  void SelectStuff() {
    DatabaseConnection& conn = factory.conn();
    conn.Execute(....);
  }
};

int main()
{
  ConnectionFactory factory;
  MayNeedDbConnection md(factory);
  md.SelectStuff();
}
bronekk
  • 2,051
  • 1
  • 16
  • 18