Возможно ли иметь конструктор с аргументами в качестве имени класса c ++? - PullRequest
0 голосов
/ 15 февраля 2012

Это пример кода для общей папки с отображенной памятью. Mapped_region - это класс d, который отвечает за него Теперь я, прежде чем копаться вглубь, не могу понять, почему используются такие декларации. Кто-нибудь может объяснить это мне?

class mapped_region
{
   // Non-copyable
   mapped_region(const mapped_region &);

   // Non-assignable
   mapped_region &operator=(const mapped_region &);

   public:

   typedef /*implementation-defined*/ offset_t;
   typedef /*implementation-defined*/ accessmode_t;
   static const accessmode_t          invalid_mode;
   static const accessmode_t          read_only;
   static const accessmode_t          read_write;
   static const accessmode_t          copy_on_write;

   mapped_region();

   mapped_region( const memory_mappable & mappable
                , accessmode_t            mode
                , offset_t                mappable_offset
                , std::size_t             size = 0
                , const void *            address = 0);

   mapped_region(mapped_region &&other);

   std::size_t get_size() const;

   void*       get_address() const;

   offset_t    get_offset() const;

   accessmode_t get_mode() const;

   void flush(std::size_t region_offset = 0, std::size_t numbytes = 0);

   void swap(mapped_region &other);

   ~mapped_region();
};

В этом примере

// Non-copyable
mapped_region(const mapped_region &); 

что это значит?

Ответы [ 5 ]

3 голосов
/ 15 февраля 2012

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

В вашем коде:

mapped_region(const mapped_region &);

представляет конструктор копирования, а:

mapped_region(mapped_region &&other);

представляет конструктор Move

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

Если вы хотите запретить пользователям вашего класса создавать копии вашего объекта класса, вы объявляете функции копирования ( конструктор копирования & оператор копирования назначения = ) как private, и это то, что ваш код делает в этом случае, он запрещает пользователям вашего кода создавать любые копии вашего класса mapped_region. Обратите внимание, что по умолчанию для класса указан спецификатор доступа private.

Поскольку ваш код объявляет конструктор Move, я предполагаю, что вы используете C ++ 11 и, следовательно, лучший способ достичь желаемой функциональности здесь - это использовать , явно удаляя специальные функции-члены предоставлено в C ++ 11.

Например:

class mapped_region{
    mapped_region & operator=(const mapped_region&) = delete;
    mapped_region(const mapped_region&) = delete;
    mapped_region() = default;
};
2 голосов
/ 15 февраля 2012

class члены по умолчанию private.

class mapped_region
{
   // Non-copyable
   mapped_region(const mapped_region &);

   // Non-assignable
   mapped_region &operator=(const mapped_region &);
public:

   //...
};

означает, что вы объявляете конструктор копирования и оператор присваивания private. Это означает, что вы не можете копировать объекты класса между собой.

2 голосов
/ 15 февраля 2012

Это конструктор копирования .Он используется для создания копии экземпляра класса.

mapped_region foo;
mapped_region bar(foo); // creates bar as copy of foo

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

1 голос
/ 15 февраля 2012
mapped_region(const mapped_region &); 

- объявление конструктора копирования.

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

mapped_region mr1;
mapped_region mr2(m1); // trying to call copy constructor call - error

или

mapped_region mr1;
mapped_region mr2 = m1; // trying to call copy constructor call - error

Комментарий:

// Non-copyable

, примененное к закрытому объявлению конструктора копирования, предполагает, что его целью является исключительно предотвращение создания компилятором по умолчанию. То же самое с operator=. Когда оба участника закрыты, вы не можете копировать или назначать один объект другому.

0 голосов
/ 15 февраля 2012

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

Если внутри класса вы пытаетесь копировать, вы получите ошибку ссылки.Так что

void mapped_region::f()
{
   mapped_region other(*this); // will compile because I have access to private functions
}

, но код не будет связываться, потому что не может найти определение конструктора копирования.(Обратите внимание, что если вы сделаете это, может быть трудно найти, куда вы копируете).

Альтернативный способ отключить копирование - извлечь ваш класс из boost :: noncopyable, таким образом:

class mapped_region : boost::noncopyable
{
   //etc.

};

и это также предотвращает назначение копирования (оператор =).Почти всегда, когда вы запрещаете копирование, вы также запрещаете копирование-назначение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...