Что делает двоеточие после имени конструктора C++, делают? [дубликат]

Пойдите с диапазоном по этим причинам:

1) xrange будет уходить в более новых версиях Python. Это дает Вам легкую будущую совместимость.

2) диапазон возьмет эффективность, связанную с xrange.

85
задан Daniel Daranas 22 July 2013 в 10:49
поделиться

9 ответов

Это список инициализации , и является частью реализации конструктора.

Подпись конструктора:

MyClass();

Это означает, что конструктор может быть вызван без параметров. Это делает его конструктором по умолчанию , т. Е. Тем, который будет вызываться по умолчанию, когда вы напишете MyClass someObject; .

Часть : m_classID (-1), m_userdata (0) называется списком инициализации . Это способ инициализировать некоторые поля вашего объекта (все они, если хотите) значениями по вашему выбору, вместо того, чтобы оставлять их как неопределенные.

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

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

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

94
ответ дан 24 November 2019 в 08:20
поделиться

Это список инициализации.

К тому времени, как вы попадаете в тело конструктора, все поля уже созданы; если у них есть конструкторы по умолчанию, они уже были вызваны. Теперь, если вы присваиваете им значение в теле конструктора, вы вызываете оператор присваивания копии, что может означать освобождение и повторное получение ресурсов (например, памяти), если у объекта они есть.

Таким образом, в случае примитивных типов, таких как int, нет никаких преимуществ по сравнению с назначением их в теле конструктора. В случае объектов, у которых есть конструктор, это оптимизация производительности, поскольку она позволяет избежать прохождения двух инициализаций объекта вместо одной.

Список инициализации необходим, если одно из полей является ссылкой, потому что ссылка никогда не может быть нулевой. , даже за короткое время между построением объекта и телом конструктора. Следующее вызывает ошибку C2758: 'MyClass :: member_': должен быть инициализирован в списке инициализаторов базы конструктора / элемента

class MyClass {
public :
    MyClass(std::string& arg) {
        member_ = arg;
    }
    std::string& member_;
};

Единственный правильный способ:

class MyClass {
public :
    MyClass(std::string& arg) 
        : member_(arg) 
    {
    }
    std::string& member_;
};
43
ответ дан 24 November 2019 в 08:20
поделиться

Обозначает начало списка инициализаторов, который предназначен для инициализации переменных-членов вашего объекта.

Что касается: MyClass (m_classID = -1, m_userdata = 0);

Это объявляет конструктор, который может принимать аргументы (чтобы я мог создать MyClass , используя MyClass m = MyClass (3, 4) , что привело бы к m_classID равно 3, а m_userdata равно 4). Если бы я не передавал никаких аргументов конструктору MyClass , это привело бы к созданию объекта, эквивалентного версии со списком инициализаторов.

2
ответ дан 24 November 2019 в 08:20
поделиться

Он сигнализирует о начале списка инициализаторов.

Также это не эквивалент MyClass (m_classId = -1, m_userData = 0). Это попытка определить конструктор с двумя параметрами, которые имеют значения по умолчанию. Однако у значений отсутствуют типы, и он вообще не должен компилироваться.

2
ответ дан 24 November 2019 в 08:20
поделиться

Это инициализация список . В вашем примере это скорее примерно так (что-то вроде этого - не означает, что он эквивалентен во всех случаях):


class MyClass {

public:

    MyClass(){
         m_classID = -1;
         m_userdata = 0;
    }

    int m_classID;
    void *m_userdata;

};
1
ответ дан 24 November 2019 в 08:20
поделиться

Это называется списком инициализации членов . Он используется для вызова конструкторов суперкласса и присвоения вашим переменным-членам начального значения в момент их создания.

В этом случае он инициализирует m_classID значением -1 и m_userData в NULL

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

1
ответ дан 24 November 2019 в 08:20
поделиться

Это не совсем оператор. Это часть синтаксиса конструктора.

Он говорит о том, что после него будет список переменных-членов и их начальных значений.

Константы-члены должны быть инициализированы таким образом. Здесь также можно инициализировать неконстантные значения, если это можно сделать с помощью одного выражения. Если для инициализации члена требуется больше кода, вы должны поместить реальный код между {}, чтобы сделать это.

Многим людям нравится помещать почти весь свой код конструктора в список инициализаторов. У меня есть коллега, который регулярно пишет классы с несколькими экранами инициализаторов, а затем помещает "{}" в код конструктора.

1
ответ дан 24 November 2019 в 08:20
поделиться

Это начало списка инициализатора, который устанавливает переменные-члены во время построения объекта. Ваш пример «MyClass (m_classID = -1, m_userdata = 0);» невозможно, так как вы не определили правильный конструктор, и вы все равно не сможете получить доступ к переменным-членам в списке параметров ... у вас может быть что-то вроде:

MyClass( int classId = -1, void* userData = 0 ) : m_classID(classId), m_userdata(userData) {}

Список инициализаторов считается лучше, чем:

MyClass( int classId = -1, void* userData = 0 ) {
    m_classID = classId;
    m_userdata = userData;
}

Google для получения дополнительной информации.

1
ответ дан 24 November 2019 в 08:20
поделиться

В этом случае: Да, ist эквивалентен, потому что рассматриваются только примитивные типы.

Если члены являются классами (структурами), вам следует предпочесть список инициализации. Это потому, что в противном случае объекты создаются по умолчанию, а затем назначаются.

0
ответ дан 24 November 2019 в 08:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: