Как я должен написать конструктор копирования в случае класса Singleton и как я должен перегружать = оператор для того же? - PullRequest
2 голосов
/ 16 января 2012

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

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

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

Ответы [ 3 ]

10 голосов
/ 16 января 2012

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

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

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

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

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

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

Вы также можете знать это: Синглтоны действительно так плохи?

7 голосов
/ 16 января 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 &);
};
0 голосов
/ 16 января 2012

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

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

, например

#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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...