Как мне написать конструктор копирования в случае класса Singleton и как мне перегрузить оператор = для него?

Как мне написать конструктор копирования для моего одноэлементного класса, чтобы предотвратить создание нового объекта, поскольку он у меня уже есть. И как лучше всего перегрузить оператор = для того же

 #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;
}       

Как написать код конструктора копирования и перегрузить оператор равенства для предотвращения создания дальнейшего объекта?


person Invictus    schedule 16.01.2012    source источник
comment
Я считаю, что лучше всего вообще не иметь синглтона. Просто не делайте больше одного, если не хотите иметь больше одного.   -  person Kerrek SB    schedule 16.01.2012
comment
@KerrekSB Что кто-то еще работает с тем же приложением, является новым для него и создает другой объект, и я не хочу, чтобы это произошло?   -  person Invictus    schedule 16.01.2012
comment
Rect * b = a; не создает второй объект. b будет указателем на   -  person Neox    schedule 16.01.2012
comment
@Neox Да, я думаю, вы правы, это неглубокая копия, и теперь b и a указывает на то же место, которое я проверил, изменив чувак, спасибо за тонну, а также я протестировал, удалив после назначения его на a, он наконец распечатывает область, но в конечном итоге дать ошибку сегментации :)   -  person Invictus    schedule 16.01.2012
comment
@Ritesh: Переосмыслить и изменить дизайн. Почему это проблема, если кто-то другой делает объект? Просто скажите им использовать ваш существующий объект. Есть разница между наличием одного объекта (прекрасно, рассмотрите возможность использования глобальной переменной) и принудительным, что только один может быть построен.   -  person Kerrek SB    schedule 16.01.2012
comment
@KerrekSB да, вы правы, но я не всегда могу попросить их использовать только один уже определенный объект .. Как всегда, большое спасибо :)   -  person Invictus    schedule 16.01.2012
comment
@Ritesh: Вы можете сделать объект недоступным для копирования, это не проблема, но это не то же самое, что и синглтон. Посмотрите на std::cout: Никто не беспокоится о том, что кто-то может случайно сделать копию этого, но это не синглтон.   -  person Kerrek SB    schedule 16.01.2012
comment
@KerrekSB Значит, вся концепция синглтона больше чушь собачья?   -  person Invictus    schedule 16.01.2012
comment
@Ritesh у него несколько применений, но количество синглтонов должно быть минимальным. Не делайте класс одноэлементным, если семантически правильно иметь только один его экземпляр в любой возможной программе, где этот класс можно было бы использовать. Синглтон - это просто класс, который может иметь только один экземпляр.   -  person    schedule 16.01.2012
comment
@ Ритеш: Да, синглтоны - это фекалии крупного рогатого скота. jalf.dk/singleton   -  person sbi    schedule 16.01.2012
comment
Другая статья и другой и другое.   -  person Kerrek SB    schedule 16.01.2012
comment
@sbi, похоже, моя ненависть к нему возросла в той же степени, что и jalf :)   -  person Invictus    schedule 16.01.2012
comment
@KerrekSB Как всегда спасибо :)   -  person Invictus    schedule 16.01.2012
comment
@WTP: не только один экземпляр класса, но и глобально доступный. Это комбинация функций, которая делает одиночные игры практически бесполезными.   -  person Xeo    schedule 16.01.2012
comment
@all Я всегда думал, что синглтон был увлекательным ... но теперь чувствую иначе :)   -  person Invictus    schedule 16.01.2012


Ответы (3)


Либо вы сделаете его не копируемым, как описано здесь

Как сделать этот объект C ++ не копируемым?

или вы определяете конструктор копирования и операторы присваивания таким образом, чтобы получить один и тот же синглтон. В зависимости от того, какая функциональность вам действительно нужна.

Назначение обычно также должно быть запрещено (как по ссылке выше):

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

Это также запрещает операции перемещения.

Вы также можете узнать следующее: Неужели синглтоны настолько плохи?

person Johan Lundberg    schedule 16.01.2012
comment
Ритеш, как вы объяснили, вы в основном хотите, чтобы ваш коллега не копировал по ошибке, так что это будет нормально. - person Johan Lundberg; 16.01.2012

Синглтоны - это смешно, используйте только бесплатные функции.

Тем не менее, чтобы ответить на ваш вопрос ...

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 &);
};
person spraff    schedule 16.01.2012

Вот соответствующий ответ: если вы не хотите, чтобы кто-то создавал объект, не давайте им общедоступный конструктор!

Серьезно, у вас может быть фабричный объект, сделать его другом для класса, создание которого вы хотите ограничить, и сделать конструктор этого класса закрытым. Таким образом, единственный способ получить доступ к объекту (даже не создавая его на данный момент) будет через вашу фабрику.

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();
}
person bronekk    schedule 16.01.2012