Странный конструктор - PullRequest
       28

Странный конструктор

2 голосов
/ 09 апреля 2010

Ну, я буду довольно прост здесь, у меня просто есть фрагмент кода на c ++, который я не уверен, что я действительно понимаю, и мне нужна помощь.

Хорошо, чтобы упростить, давайте просто скажем, что у меня есть класс, который определен так: (настоящий класс немного сложнее, но это то, что имеет значение)

class myClass : public Runnable {
    Semaphore *m_pMySemaphore;
    __Queue<Requests> *m_pQueue;
    Request m_Request;
    VetorSlotBuffer *m_vetorSlotBuffer;
}

До сих пор в этом нет ничего плохого, myClass - это обычный класс, имеющий 3 члена, которые фактически являются указателями на другие классы и объектом класса Request, реализация этих классов не важна для моей точки зрения здесь. *

Затем, когда этот человек реализовал конструктор для myClass, он или она сделали это:

myClass::myClass() : m_pMySemaphore(0), m_pQueue(0), m_vetorSlotBuffer(0) { }

Довольно очевидно, что эти три переменные обрабатываются конструктором так, потому что они являются указателями, я прав? но что это за синтаксис? я устанавливаю указатели на ноль, делая это? Я уже видел немного с ++, но ничего подобного не нашел.

А во-вторых, как обстоят дела с ":" после объявления конструктора? что я видел, но никогда не занимал время для расследования. Это как внутренний класс или что-то в этом роде?

Большое спасибо заранее. Нельсон Р. Перес

Ответы [ 4 ]

8 голосов
5 голосов
/ 09 апреля 2010

Это инициализация элемента при создании объекта, называемая списком инициализации.
Вы не можете инициализировать их в другом месте, скажем:

class X { 
    int i = 0; // error bad syntax
} 

Ни в конструкторе с помощью присваивания, если они const:

class X { 
    const int i; 
    X(){ 
        i = 0; // error it's a const
    } 
} 

Итак, ребята из c ++ создали этот синтаксис!

4 голосов
/ 09 апреля 2010

Да, эти указатели инициализируются в NULL. Ключевым моментом здесь является то, что они инициализируются, а не назначаются. I.e.:

myClass::myClass()
  :  m_pMySemaphore(0),   // initialized to 0
     m_pQueue(NULL)      // initialized to NULL (preferable to 0)
                         // no initializer for m_Request - uses default constructor
                         // no initializer for m_vectorSlotBuffer
{
   // at this point, the object is entirely initialized, and can be used.

   // this next line ASSIGNS to the member
   m_vectorSlotBuffer = 0;
}

Что происходит с m_vectorSlotBuffer, так это то, что он инициализируется, а затем назначается в два отдельных этапа. Делая это как m_pQueue, мы сохраняем шаг и правильно инициализируем. Это становится очень важным, когда мы хотим использовать конструктор не по умолчанию или если мы хотим инициализировать const членов.

Кроме того, : после конструктора () - это то, что начинает раздел инициализации, прежде чем мы перейдем к {, где мы вводим тело конструктора.

Наконец, NULL не гарантируется равным 0. NULL является переносимым, но большинство архитектур используют 0 в качестве NULL.

РЕДАКТИРОВАТЬ : 0 / НЕДЕЙСТВИТЕЛЬНОЕ различие больше не имеет смысла. Просто выберите один и будьте последовательны.

3 голосов
/ 09 апреля 2010

Да, указатели со значением 0 - это указатели со значением NULL.

Синтаксис : для конструкторов называется списками инициализации. Он используется здесь для простой и прямой инициализации полей-членов. Должно быть легко гуглить с правильной терминологией.

...