Как работает преобразование конструктора в C ++?

Как работает преобразование конструктора?

#include <iostream>
using namespace::std;

class One {
public:
One() { cout<<"One"<<endl;}
};

class Two {
public:
Two(const One&) {cout<<"Two(const One&)"<<endl;}
};

void f(Two) {cout<<"f(Two)"<<endl;}

int main() {
One one;
f(one);
}

производит вывод

One
Two(const One&)
f(Two)

0

Решение

Любой конструктор, который может быть вызван с одним аргументом, считается implicit conversion constructor, Это включает простые случаи с 1 аргументом и использование аргументов по умолчанию.

Это преобразование рассматривается в любом контексте, который хочет X и предоставил Y, и Y имеет такую ​​неявную возможность преобразования. Обратите внимание, что множество других встроенных преобразований также играют роль микса (например, регулировка константности, интегральных и fp-продвижений, преобразований и т. Д.). Правило состоит в том, что не более одного «определенного пользователем» неявного преобразования разрешено в перемешать.

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

В качестве примера рассмотрим std::vector у которого ctor принимает size_t, устанавливая начальный размер. Это явно — иначе ваш foo(vector<double> const& ) функция может быть ошибочно вызвана с помощью foo (42).

3

Другие решения

Это правильный результат. поскольку constructor не является explicit — неявное преобразование работает (здесь One неявно преобразуется в Two).

one создается, а затем при передаче f конвертировано в Two,

0

Что за Two(const One&) {cout<<"Two(const One&)"<<endl;} Конструктор означает, что вы можете построить Two значение в любое время — неявно — от One, Когда вы звоните f(one) он хочет Two параметр, это дано Oneпоэтому компилятор соединяет 2 и 2 вместе и говорит: «Я сделаю временный Two от One и завершите звонок f()«… все будут счастливы. Ура!

0

Компилятор должен создать копию Two экземпляр в стеке. Когда вы звоните f() с аргументом, который является объектом класса One (или любой другой) компилятор смотрит на определение класса Two и пытается найти конструктор, который принимает One(или любой другой) объект (или ссылка) в качестве аргумента. Когда такой конструктор найден, он создает объект, используя его. Это называется неявным, потому что компилятор делает это без вашего вмешательства.

class Foo {
public:
Foo(int number) {cout<<"Foo(int number)"<<endl;}
};

void f(Foo) {cout<<"f(Foo)"<<endl;}

int main() {
f(24);
} ///:~

Выход будет:
Foo (внутренний номер)
F (Foo)

0
По вопросам рекламы ammmcru@yandex.ru