Почему это работает, чтобы возвращать int в методе, который должен возвращать объект?
Почему это работает, чтобы вернуть int
в метод B minus
, если предполагается, что метод возвращает объект типа B
?
#include <iostream>
class B
{
public:
int a;
public:
B(int i=0)
{
a=i;
}
B minus()
{
return (1-a);
}
};
int main()
{
B x(18);
x = x.minus();
std::cout << x.a << '\n';
return 0;
}
Ответы
Ответ 1
Конструктор с единственным аргументом считается конструктором преобразования. Когда требуется аргумент типа X, и вместо него указывается тип Y, компилятор будет искать конструктор преобразования (или оператор преобразования типа) из Y в X. В этом случае он находит один, используя ваш конструктор B(int)
, По существу, ваш return (1-a);
изменен на return B(1-a);
.
Как упоминалось в нескольких других (также правильных) ответах, если вы не хотите, чтобы конструктор считался конструктором преобразования, вы должны указать его с помощью ключевого слова explicit
.
Ответ 2
Линия
return (1-a);
вызывает конструктор неявного преобразования
B(int i=0)
{
a=i;
}
Итак, это то же самое, что писать
return B(1-a);
Обратите внимание, что конструктор копирования все еще сгенерирован, если вы не delete
его.
Если вы хотите этого избежать, напишите
explicit B(int i=0)
// ^^^^^^^^
{
a=i;
}
это заставит пользователя писать
return B(1-a);
Ответ 3
Это происходит потому, что конструктор с одним аргументом может использоваться как неявный приведение из типа аргумента в тип объекта.
В вашем случае у вас есть конструктор, который принимает аргумент типа int
, поэтому этот конструктор можно использовать для преобразования int
в B
.
Чтобы предотвратить использование этих конструкторов при преобразовании, вы должны пометить конструктор explicit
- и это хорошая практика для всех конструкторов с одним аргументом, поскольку на практике эти неявные преобразования чаще всего нежелательны, чем желательно.