Подтвердить что ты не робот

Почему это работает, чтобы возвращать 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;
}
4b9b3361

Ответ 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 - и это хорошая практика для всех конструкторов с одним аргументом, поскольку на практике эти неявные преобразования чаще всего нежелательны, чем желательно.