Konwersje
Element konwersji tworzy nową wartość określonego typu z wartość innego typu.Konwersji standardowych są tworzone w języku C++ i pomocy technicznej, można utworzyć jej wbudowane typy, a zdefiniowanych przez użytkownika konwersje można wykonać konwersji do, z lub między typów zdefiniowanych przez użytkownika.
Konwersji standardowych wykonać konwersji między wbudowane typy, między wskaźniki lub odwołuje się do typy powiązane z dziedziczenie do i z void wskaźników i wskaźnik zerowy.Aby uzyskać więcej informacji, zobacz Konwersje standardowe.Zdefiniowane przez użytkownika konwersje wykonać konwersji między typów zdefiniowanych przez użytkownika lub typów zdefiniowanych przez użytkownika i wbudowane typy.Można zaimplementować je jako konstruktorów konwersji lub jako funkcje konwersji.
Konwersje może być jawne — gdy programisty wywołuje dla jednego typu do przekonwertowania na inny, tak jak cast lub inicjowania bezpośrednie — lub niejawnych — Jeśli język lub program wymaga innego typu niż podany przez programistę.
Konwersje niejawne są próby po:
Argument przekazany do funkcji nie ma tego samego typu co zgodnych parametrów.
Wartość zwrócona przez funkcję nie ma tego samego typu jako typ zwrotny funkcji.
Wyrażenia inicjatora nie ma tego samego typu co obiekt, który jest podczas inicjowania.
Wyrażenie, które steruje instrukcję warunkową, konstrukcji pętli lub przełącznik nie ma typ wyniku, które są wymagane do kontrolowania go.
Argument dostarczonych operator nie ma tego samego typu co zgodnych parametrów argument operacji.Wbudowane operatorów oba argumenty muszą być tego samego typu, a są konwertowane na typ wspólne, który może reprezentować obu.Aby uzyskać więcej informacji, zobacz Konwersje arytmetyczne.Dla operatorów zdefiniowanych przez użytkownika każdy argument musi mieć tego samego typu co zgodnych parametrów argument operacji.
Podczas konwersji standardowych jednego nie może ukończyć niejawna, kompilator można użyć konwersji zdefiniowanej przez użytkownika, oraz opcjonalnie dodatkowe standardowych konwersji do jego wykonania.
Co najmniej dwa zdefiniowanych przez użytkownika konwersje, które dokonać konwersji tej samej są dostępne w witrynie konwersji, konwersji jest określane jako niejednoznaczne.Takie niejasności są wystąpił błąd, ponieważ kompilator nie można określić jedną z dostępnych konwersje należy wybrać.Jednak nie jest błąd tak, aby zdefiniować wiele sposobów wykonywania tej samej konwersji, ponieważ zestaw dostępnych konwersji mogą być różne w różnych miejscach w kodzie źródłowym — na przykład, w zależności od tego, które nagłówka pliki znajdują się w pliku źródłowym.Tak długo, jak tylko jeden konwersji jest dostępna w witrynie konwersji, nie ma żadnych niejednoznaczności.Istnieje kilka sposobów, mogą się pojawić Niejednoznaczne konwersje, którzy są najczęściej następujące:
Wiele dziedziczenia.Konwersja jest zdefiniowana w klasie podstawowej więcej niż jeden.Aby uzyskać więcej informacji, zobacz Niejednoznaczność.
Wywołanie funkcji niejednoznaczne.Konwersja jest zdefiniowany jako konstruktora konwersji typu docelowego, a funkcja konwersji typu źródła.Aby uzyskać więcej informacji, zobacz funkcje konwersji.
Niejednoznaczność może zostać rozwiązany zwykle tylko przez odpowiednich nazwę typu biorących udział w pełnym lub wykonując jawnego rzutowania wyjaśnienie Twój profil konwersji.
Zarówno konstruktorów konwersji i funkcje konwersji przestrzegać zasad kontroli dostępu do elementu członkowskiego, ale dostępności konwersje uznaje tylko wtedy, gdy można ustalić jednoznaczne konwersji.Oznacza to, że konwersja może być niejednoznaczne nawet wtedy, gdy poziom dostępu konkurencyjnych konwersji może uniemożliwić jej jest używany.Aby uzyskać więcej informacji o dostępności elementu członkowskiego, zobacz Kontrola dostępu do elementów członkowskich.
Słowo kluczowe jawne i problemy z konwersji niejawnych
Domyślnie po utworzeniu konwersji zdefiniowanej przez użytkownika, kompilator służy do wykonywania konwersji niejawnych.Jest to tego, czego szukasz, ale innym razem prostych reguł, które prowadzą do zgłoszenia konwersje niejawne kompilator może doprowadzić do kodu, których nie chcesz, aby zaakceptować.
Dobrze znanych przykładem niejawna konwersja, które mogą powodować problemy jest konwersji na bool.Istnieje wiele przyczyn, które można utworzyć typu klasy, który może być używany w kontekście logiczną — na przykład, tak aby służy do sterowania if instrukcji lub pętli —, ale gdy kompilator wykona zdefiniowaną przez użytkownika konwersja na wbudowany typ, kompilator może zastosować później dodatkowe standardowych konwersji.To dodatkowe standardowych konwersji wprowadza zezwalająca na czynności promocji z short do int, ale otwiera również drzwi dla mniej widocznych konwersji — na przykład z bool do int, co umożliwia używanego typu klasy do użycia w kontekstach całkowitą nie powinny.Tego konkretnego problemu jest nazywana awaryjnym Problem wartość logiczna.Tego rodzaju problemy jest where explicit może pomóc słowo kluczowe.
explicit Słowo kluczowe informuje kompilator, że nie można użyć określonej konwersji można wykonać konwersji niejawnych.Jeśli potrzebujesz składni wygodą konwersje niejawne przed explicit wprowadzono słowo kluczowe, należało Zaakceptuj niepożądanych skutków takiej konwersji niejawnych czasami utworzony lub użyć funkcji konwersji mniej wygodny, nazwany jako alternatywy.Teraz, za pomocą explicit słowo kluczowe, możesz utworzyć wygodny konwersji, który można użyć tylko można wykonać rzutowania jawne lub bezpośrednie inicjowania i nie będzie prowadzących do rodzaju problemy wyjaśnienie działania na awaryjnym Problem wartość logiczna.
explicit Słowo kluczowe można zastosować do konwersji konstruktorów od C ++ 98 oraz funkcje konwersji, ponieważ C ++ 11.Następujące sekcje zawierają więcej informacji na temat sposobu używania explicit słowo kluczowe.
Konstruktory konwersji
Konstruktory konwersji zdefiniuj konwersje ze zdefiniowaną przez użytkownika lub wbudowane typy do typu zdefiniowane przez użytkownika.W poniższym przykładzie pokazano konwersję konstruktora, który konwertuje wbudowany typ double do typu zdefiniowane przez użytkownika Money.
#include <iostream>
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
double amount;
};
void display_balance(const Money balance)
{
std::cout << "The balance is: " << balance.amount << std::endl;
}
int main(int argc, char* argv[])
{
Money payable{ 79.99 };
display_balance(payable);
display_balance(49.95);
display_balance(9.99f);
return 0;
}
Uwaga dotycząca, że pierwsze wywołanie funkcji display_balance, która wymaga argumentu typu Money, nie wymaga konwersji, ponieważ jej argument jest poprawnego typu.Jednakże w przypadku drugie wywołanie display_balance, wymagany jest konwersji, ponieważ typ argumentu double o wartości 49.95, jest nie co funkcja oczekuje.Funkcji nie można użyć tej wartości bezpośrednio, ale, ponieważ jest konwersja z typu argumentu —double— na typ parametru zgodnych —Money— tymczasowe wartości typu Money jest skonstruowany na podstawie argument i służą do zakończenia wywołania funkcji.W wywołaniu trzeci display_balance, należy zauważyć, że argument nie jest double, ale zamiast tego jest float o wartości niż 9,99— i jeszcze wywołania funkcji nadal można zakończone, ponieważ kompilator można wykonać konwersji standardowych — w tym przypadku z float do double—, a następnie przeprowadzić konwersji zdefiniowane przez użytkownika z double do Money do ukończenia na potrzeby konwersji.
Deklarującego konstruktorów konwersji
Poniższe reguły dotyczą deklarującego konstruktora konwersji:
Typ docelowy konwersji jest typu zdefiniowane przez użytkownika, którego jest budowany.
Konwersja konstruktorów zwykle wykonywanych dokładnie jeden argument, który jest typu źródła.Jednak Konstruktor konwersji można określić dodatkowe parametry, jeśli każdy dodatkowy parametr ma wartość domyślną.Typ źródła pozostaje typ pierwszego parametru.
Konstruktory konwersji, takich jak wszystkie konstruktorów nie należy określać typ zwrotny.Określanie zwracany typ w deklaracji występuje błąd.
Konwersja konstruktorów może być jawne.
Konwersja jawna konstruktorów
Przez konstruktora konwersji do deklarowania explicit, może być używane tylko, można wykonać bezpośrednie inicjowania obiektu lub do wykonania jawnego rzutowania.Pozwala to zapobiec funkcji zaakceptować argumentu typu klasy również niejawnie akceptowanie argumentów konstruktora konwersji typu źródła i zapobiega typu klasy kopiowania zainicjowana z wartości typu źródła.Poniższy przykład pokazuje, jak zdefiniować konstruktora konwersji jawnej, a efekt, który ma go w jaki kod jest poprawnie sformułowany.
#include <iostream>
class Money
{
public:
Money() : amount{ 0.0 } {};
explicit Money(double _amount) : amount{ _amount } {};
double amount;
};
void display_balance(const Money balance)
{
std::cout << "The balance is: " << balance.amount << std::endl;
}
int main(int argc, char* argv[])
{
Money payable{ 79.99 }; // Legal: direct initialization is explicit.
display_balance(payable); // Legal: no conversion required
display_balance(49.95); // Error: no suitable conversion exists to convert from double to Money.
display_balance((Money)9.99f); // Legal: explicit cast to Money
return 0;
}
W tym przykładzie zwróć uwagę na to można nadal używać konstruktora konwersji jawnej można wykonać bezpośrednie inicjowanie payable.Jeśli zamiast tego była do inicjalizacji kopii Money payable = 79.99;, możesz ją wystąpił błąd.Pierwsze wywołanie funkcji display_balance nie ma wpływu, ponieważ argument jest poprawnego typu.Drugie wywołanie display_balance jest błąd, ponieważ konstruktora konwersji nie można używać do wykonywania konwersje niejawne.Trzeci wywołanie display_balance jest dozwolony z powodu jawnego rzutowanie Money, ale Zauważ, że kompilator nadal przydatne ukończyć rzutowania wstawiając niejawne rzutowanie ze float do double.
Chociaż wygodą stosowanie konwersje niejawne może być kuszące, spowoduje może więc wprowadzić usterki trudne do znalezienia.Zasadą jest zapewnienie jawne, z wyjątkiem przypadków, gdy wiesz ma określone konwersji występuje niejawnie wszystkich konstruktorów konwersji.
Funkcje konwersji
Funkcje konwersji zdefiniuj konwersji z typu zdefiniowanego przez użytkownika na inne typy.Te funkcje są niekiedy mianem "cast operatorów", ponieważ ich, wraz z konstruktorów konwersji są wywoływane, gdy wartość jest rzutowane na inny typ.W poniższym przykładzie pokazano funkcję konwersji, która konwertuje z typu zdefiniowane przez użytkownika, Money, typem wbudowane double:
#include <iostream>
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
operator double() const { return amount; }
private:
double amount;
};
void display_balance(const Money balance)
{
std::cout << "The balance is: " << balance << std::endl;
}
Należy zauważyć, że zmienna członka amount zostanie wykonane prywatne i publiczne konwersji funkcji wpisz double wprowadza się tylko do zwracania wartości amount.W funkcji display_balance, niejawna konwersja występuje, gdy wartość balance przesyłanego strumieniowo do wyjścia standardowego za pomocą operatora wstawiania strumienia <<.Ponieważ żaden operator wstawiania strumień jest zdefiniowany dla typu zdefiniowane przez użytkownika Money, ale jest on dostępny dla wbudowany typ double, kompilator można użyć funkcji konwersji z Money do double przez operatora wstawiania strumienia.
Funkcje konwersji są dziedziczone przez klasy pochodnej.Funkcje konwersji w klasie pochodnej tylko musi zostać zastąpiona w funkcji konwersji odziedziczone po konwertują do tego samego typu.Na przykład funkcja zdefiniowana przez użytkownika konwersja klasy pochodnej operator int nie zastępuje — lub nawet wpływu — funkcja zdefiniowana przez użytkownika konwersja klasy bazowej operator short, nawet jeśli konwersji standardowych definiowania relacji konwersji między int i short.
Deklarującego funkcje konwersji
Poniższe reguły dotyczą deklarującego funkcji konwersji:
Typ docelowy konwersji musi być zadeklarowany przed deklaracji funkcji konwersji.Nie można zadeklarować klasy, struktury, wyliczenia i definicje typów w deklaracji funkcji konwersji.
operator struct String { char string_storage; }() // illegal
Funkcje konwersji nie przyjmuje żadnych parametrów.Określanie parametrów w deklaracji występuje błąd.
Funkcje konwersji ma typ zwrotny jest określona przez nazwę funkcję konwersji, która jest również nazwę typu docelowego konwersji.Określanie zwracany typ w deklaracji występuje błąd.
Funkcje konwersji może być wirtualnego.
Funkcje konwersji może być jawne.
Konwersji jawnej
Gdy funkcji konwersji jest zadeklarowany jako jawne, go tylko służy do wykonania jawnego rzutowania.Pozwala to zapobiec funkcji zaakceptować argument funkcji konwersji typu docelowego również niejawnie akceptowanie argumenty typu klasy i zapobiega wystąpienie typu docelowego kopii zainicjowana z wartości typu klasy.Poniższy przykład pokazuje, jak zdefiniować funkcję konwersji jawnej i efekt cechuje się na jakie kod jest poprawnie sformułowany.
#include <iostream>
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
explicit operator double() const { return amount; }
private:
double amount;
};
void display_balance(const Money balance)
{
std::cout << "The balance is: " << (double)balance << std::endl;
}
Tutaj funkcji konwersji operator double została przeprowadzona jawne i jawne Rzutowanie na typ double została wprowadzona w funkcji display_balance można wykonać konwersji.Jeśli tego rzutowania zostały pominięte, kompilator będzie nie można zlokalizować operatorem odpowiedniego wstawiania strumienia << dla typu Money i wystąpi błąd.