Wywołanie funkcji podając jedynie argument konstruktora obiektu

0

Witam, przerabiam różne przykłady z C++ i natrafiłem na jeden który mnie zaciekawił. Chciałbym się was zapytać jakim cudem mogę wywołać f(3)? Rozumiem jakbym to zrobił
w taki sposób f(A(3)), ale dlaczego skoro funkcja oczekuje obiektu klasy const A &a1, a dostaje int, to nie protestuje tylko uruchamia konstruktor z parametrem int klasy A ?

#include<iostream> 
using namespace std;

class A
{
public:
	A(int n = 0) : m_n(n)
	{
		std::cout << 'd';
	}

	A(const A& a)
		: m_n(a.m_n)
	{
		std::cout << 'c';
	}

private:
	int m_n;
};

void f(const A &a1, const A &a2 = A())
{
	cout << "f";
}

int main()
{
	f(3);
	getchar();
	return 0;
}

3

po prostu w C++ każdy konstruktor,który można wywołąć z jednym argumentem jest traktowany jako domyślna konwersja z typu argumentu tego konstruktora do tego obiektu.
Jak poprzedzisz konstruktor słowem kluczowym explicit to ten "feature" się wyłączy.
Używanie explicit jest wręcz rekomendowane by unikać niespodziewanych konwersji.

0

Gdzie taki kod znalazłeś ? m_n(n) to chodzi o to że jest wpisywana wartość do pola m_n tak ?

0
profesorek96 napisał(a):

Gdzie taki kod znalazłeś ? m_n(n) to chodzi o to że jest wpisywana wartość do pola m_n tak ?

Podałem jedynie wycinek
http://www.interqiew.com/ask?ta=tqcpp01&qn=1

0
MarekR22 napisał(a):

po prostu w C++ każdy konstruktor,który można wywołąć z jednym argumentem jest traktowany jako domyślna konwersja z typu argumentu tego konstruktora do tego obiektu.

z wieloma argumentami tez. na szczescie jest to nieco mniej irytujace bo przy wywloaniu widac ze programista cos knuje:

f({1, 5})
0

Mam podobny problem, tutaj z kolei zostanie wybrany konstruktor przyjmujący argument jako int ponieważ nie ma konstruktora przyjmującego char. Nie wiem czemu tak się dzieje, myślałem, że i w tym przypadku explicit może zapobiec konwersji, ale tak nie jest.

#include<iostream>
using namespace std;

class IndiaBix
{
	int x;
public:
	IndiaBix(short ss)
	{
		cout << "Short" << endl;
	}
	explicit IndiaBix(int xx)
	{
		cout << "Int" << endl;
	}

	IndiaBix(float ff)
	{
		cout << "Float" << endl;
	}
	~IndiaBix()
	{
		cout << "Final";
	}
};

int main()
{
	IndiaBix *ptr = new IndiaBix('B');
	getchar();
	return 0;
}
0

A to dlatego, że zachodzi konwersja chart na int. Explicit służy do ograniczenia niejawnego rzutowania w stylu:

Foo f = 5;

a nie do wykluczania konwersji między typami podstawowymi.

Jak chcesz mieć klarowną sytuacją do co wywołań to po prostu nie twórz x konstruktorów z jednym parametrem typu bazowego, wtedy nie będziesz miał takich kwiatków.

I na litość, daj sobie spokój z new, którego nawet nie usuwasz.

0

konwersja z char do int jest domyślna z definicji samego języka.
explicit nie ma tu nic do gadania, bo nie jest wykorzystywana konwersja zdefiniowana przez ciebie.
A jako, że wywołałeś konstruktor jawnie, to kompilator odszukał najlepiej pasujący konstruktor, który wykorzysta standardową konwersję.

1 użytkowników online, w tym zalogowanych: 0, gości: 1