Назначение против инициализации в C ++ - PullRequest
7 голосов
/ 20 февраля 2010

Я думал, что конструкторы управляют инициализацией, а оператор = функции управляют назначением в C ++. Так почему этот код работает?

#include <iostream>
#include <cmath>
using namespace std;

class Deg {
    public:
        Deg() {}
        Deg(int a) : d(a) {}        
        void operator()(double a)
        {
            cout << pow(a,d) << endl;
        }

    private:
        int d;
};

int
main(int argc, char **argv) 
{
    Deg d = 2;
    d(5);
    d = 3; /* this shouldn't work, Deg doesn't have an operator= that takes an int */
    d(5);
    return 0;
}

В третьей строке основной функции я присваиваю int объекту класса Deg. Поскольку у меня нет функции operator=(int), я подумал, что это, безусловно, не получится ... но вместо этого она вызывает конструктор Deg(int a). Так конструкторы также управляют назначением?

Ответы [ 2 ]

18 голосов
/ 20 февраля 2010

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

explicit Deg(int a) : d(a) {}

4 голосов
/ 20 февраля 2010

Просто чтобы уточнить ответ JonM:

Для строки d = 3 задействован оператор присваивания . 3 неявно преобразуется в Deg, как сказал JonM, и затем Deg является назначенным на d с использованием сгенерированного компилятором оператора присваивания (который по умолчанию делает член-член мудрое задание). Если вы хотите запретить присваивание, вы должны объявить частный оператор присваивания (и не реализовывать его):

//...
private:
    Deg& operator=(const Deg&);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...