2010-02-20 3 views
7

Я думал, что конструкторы управляют инициализацией и присваиванием функций operator = functions в C++. Так почему же этот код работает?Назначение против инициализации в 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). Так и конструкторы также управляют назначением?

ответ

18

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

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

+0

+1 явной – dimba

+3

По крайней мере одной компании я работал уже имели правило «использовать явный на все конструкторы, если нет веских оснований не «среди своих стандартов кодирования». Это помогает избежать потенциально загадочных ситуаций, подобных этому. – Sean

+0

Я полагаю, вы имеете в виду все конструкторы, которые могут быть вызваны одним аргументом :)? –

4

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

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

//... 
private: 
    Deg& operator=(const Deg&); 
} 
Смежные вопросы