Jaka jest preferowana metoda uzyskania równoważnika C++ z instanceof
?C++ odpowiednik instanceof
Odpowiedz
Spróbuj użyć:
if(NewType* v = dynamic_cast<NewType*>(old)) {
// old was safely casted to NewType
v->doSomething();
}
Wymaga kompilatora mieć RTTI wsparcie włączona.
EDYCJA: Mam kilka dobrych komentarzy na temat tej odpowiedzi!
Za każdym razem, gdy trzeba użyć dynamic_cast (lub instanceof), lepiej zadać sobie pytanie, czy jest to konieczne. Jest to ogólnie oznaką złego projektu.
Typowe obejścia polegają na wprowadzeniu zachowania specjalnego dla klasy, do której się sprawdza, w funkcji wirtualnej na klasie bazowej lub wprowadzeniu czegoś takiego jak visitor, w którym można wprowadzić określone zachowanie dla podklas bez zmiany interfejsu (z wyjątkiem dodawania interfejs akceptacji odwiedzających oczywiście).
Jak wskazano, dynamic_cast nie przychodzi za darmo. Prostym i konsekwentnie wykonywanym hackem, który obsługuje większość (ale nie wszystkie przypadki), jest dodanie ekwipunku reprezentującego wszystkie możliwe typy, które może posiadać twoja klasa i sprawdzenie, czy masz właściwą.
if(old->getType() == BOX) {
Box* box = static_cast<Box*>(old);
// Do something box specific
}
To nie jest dobry z projektu, ale może to być obejście, a jej koszt jest mniej więcej tylko wirtualne wywołanie funkcji. Działa również niezależnie od RTTI jest włączona, czy nie.
Należy zauważyć, że takie podejście nie obsługuje wiele poziomów dziedziczenia, więc jeśli nie jesteś ostrożny może skończyć się kod wygląda tak:
// Here we have a SpecialBox class that inherits Box, since it has its own type
// we must check for both BOX or SPECIAL_BOX
if(old->getType() == BOX || old->getType() == SPECIAL_BOX) {
Box* box = static_cast<Box*>(old);
// Do something box specific
}
musi mieć co najmniej jedną wirtualną metodę, aby to zadziałało – vava
Zwykle tak jest, gdy wykonujesz test "instanceof" – Laserallan
Jeśli muszą używać instanceof, w większości przypadków coś jest nie tak z twoim projektem. – mslot
#include <iostream.h>
#include<typeinfo.h>
template<class T>
void fun(T a)
{
if(typeid(T) == typeid(int))
{
//Do something
cout<<"int";
}
else if(typeid(T) == typeid(float))
{
//Do Something else
cout<<"float";
}
}
void main()
{
fun(23);
fun(90.67f);
}
To jest naprawdę zły przykład. Dlaczego nie skorzystać z przeciążenia, czyli taniej? – user1095108
Głównym problemem jest to, że nie odpowiada na pytanie. 'instanceof' pyta o typ dynamiczny, ale w tej odpowiedzi typ dynamiczny i statyczny zawsze odpowiadają. – MSalters
@HHH odpowiesz jest o krok od pytania! – programmer
W zależności od tego, co chcesz zrobić ci może to zrobić:
template<typename Base, typename T>
inline bool instanceof(const T*) {
return std::is_base_of<Base, T>::value;
}
Zastosowanie:
if (instanceof<BaseClass>(ptr)) { ... }
Jednak to działa wyłącznie na typach znanych kompilatorowi.
Edit:
Kod ten powinien działać na polimorficznych wskazówek:
template<typename Base, typename T>
inline bool instanceof(const T *ptr) {
return dynamic_cast<const Base*>(ptr) != nullptr;
}
Przykład: http://cpp.sh/6qir
Eleganckie i dobrze wykonane rozwiązanie. +1 Ale uważaj, aby uzyskać prawidłowy wskaźnik. Nie dotyczy wskaźnika polimorficznego? –
Co się stanie, jeśli wskażemy wskaźnik przy korzystaniu z tej funkcji? Czy wtedy działałoby na wskaźniki polimorficzne? –
Nie działa to tylko na typach znanych kompilatorowi. Nie będzie działał z wskaźnikami polimorficznymi, bez względu na to, czy zniknąłeś, czy nie. Dodam coś, co może działać w tym przypadku. – panzi
Ten pracował dla mnie idealny przy użyciu kodu :: Blocks IDE kompilator GCC z
#include<iostream>
#include<typeinfo>
#include<iomanip>
#define SIZE 20
using namespace std;
class Publication
{
protected:
char title[SIZE];
int price;
public:
Publication()
{
cout<<endl<<" Enter title of media : ";
cin>>title;
cout<<endl<<" Enter price of media : ";
cin>>price;
}
virtual void show()=0;
};
class Book : public Publication
{
int pages;
public:
Book()
{
cout<<endl<<" Enter number of pages : ";
cin>>pages;
}
void show()
{
cout<<endl<<setw(12)<<left<<" Book Title"<<": "<<title;
cout<<endl<<setw(12)<<left<<" Price"<<": "<<price;
cout<<endl<<setw(12)<<left<<" Pages"<<": "<<pages;
cout<<endl<<" ----------------------------------------";
}
};
class Tape : public Publication
{
int duration;
public:
Tape()
{
cout<<endl<<" Enter duration in minute : ";
cin>>duration;
}
void show()
{
cout<<endl<<setw(10)<<left<<" Tape Title"<<": "<<title;
cout<<endl<<setw(10)<<left<<" Price"<<": "<<price;
cout<<endl<<setw(10)<<left<<" Duration"<<": "<<duration<<" minutes";
cout<<endl<<" ----------------------------------------";
}
};
int main()
{
int n, i, type;
cout<<endl<<" Enter number of media : ";
cin>>n;
Publication **p = new Publication*[n];
cout<<endl<<" Enter "<<n<<" media details : ";
for(i=0;i<n;i++)
{
cout<<endl<<" Select Media Type [ 1 - Book/2 - Tape ] ";
cin>>type;
if (type == 1)
{
p[i] = new Book();
}
else
if (type == 2)
{
p[i] = new Tape();
}
else
{
i--;
cout<<endl<<" Invalid type. You have to Re-enter choice";
}
}
for(i=0;i<n;i++)
{
if (typeid(Book) == typeid(*p[i]))
{
p[i]->show();
}
}
return 0;
}
@Andres proszę przeczytać pytanie przed wysłaniem odpowiedzi. – programmer
@programm Myślę, że masz na myśli wywołanie @pgp, po prostu naprawiłem jego formatowanie kodu. Ponadto, jego odpowiedź wydaje się być w zasadzie "use' typeid' ", która jest błędna (" Nie ma gwarancji, że ta sama instancja std :: type_info będzie odwoływać się do wszystkich ocen wyrażenia typu typid na tym samym typie ... 'assert (typeid (A) == typeid (A));/* nie jest gwarantowane * /' ", patrz [cppreference.com] (http://en.cppreference.com/w/cpp/language/typeid#Notes)), wskazuje, że przynajmniej próbował odpowiedzieć na to pytanie, jeśli nie jest to pomocne, ponieważ zaniedbał oferowanie minimalnego przykładu pracy. –
@Andreas, przepraszam! moje złe, będę edytować post. – programmer
dynamic_cast
jest znany jako nieefektywny. Przechodzi do hierarchii dziedziczenia i jest jedynym rozwiązaniem, jeśli masz wiele poziomów dziedziczenia i trzeba sprawdzić, czy obiekt jest instancją dowolnego typu w hierarchii typów.
Ale jeśli bardziej ograniczona forma instanceof
że tylko sprawdza, czy dany przedmiot jest dokładnie typ określić, wystarczy do swoich potrzeb, funkcja poniżej byłoby dużo bardziej wydajny:
template<typename T, typename K>
inline bool isType(const K &k) {
return typeid(T).hash_code() == typeid(k).hash_code();
}
Oto przykład od tego, jak chcesz wywołać funkcję powyżej:
DerivedA k;
Base *p = &k;
cout << boolalpha << isType<DerivedA>(*p) << endl; // true
cout << boolalpha << isType<DerivedB>(*p) << endl; // false
można by określić rodzaj szablonu A
(jako typ jesteś sprawdzanie) i przechodzą w obiekcie, który chcesz przetestować jako argument (z których szablon typu K
można wywnioskować).
- 1. instanceof odpowiednik dla Object.create i prototypowych łańcuchów
- 2. instanceof dla obiektów w C++ (nie wskazówek)
- 3. Odpowiednik iif w C#
- 4. Odpowiednik Double.DoubleToLongBits w C#?
- 5. C# odpowiednik jQuery.parents (Type)
- 6. C odpowiednik zerknięcia fstreama
- 7. SAXParser odpowiednik w C#
- 8. Odpowiednik constexpr z C++?
- 9. C# odpowiednik "Not MyEnum.SomeValue"
- 10. C++ odpowiednik "super"?
- 11. C++ odpowiednik Java ByteBuffer?
- 12. C++ odpowiednik .NET's Task.Delay?
- 13. C# odpowiednik perla $ _
- 14. Java: Instanceof i Generics
- 15. instanceof z kolekcją generyczną
- 16. instanceof i nazw
- 17. JavaScript instanceof if
- 18. instanceof w Grails
- 19. Użyj instanceof w Thymeleaf
- 20. instanceof vs isinstance()
- 21. Odpowiednik C++/CLI słowa kluczowego C# 'readonly'
- 22. Czy istnieje odpowiednik statycznego C w C#?
- 23. Objective-C odpowiednik "override" w C#
- 24. C# odpowiednik wektora C++ z przyległą pamięcią?
- 25. ANSI C odpowiednik try/catch?
- 26. Dowolny odpowiednik "rozszerzony" dla C#?
- 27. IsNullOrEmpty odpowiednik dla Array? C#
- 28. C# odpowiednik php asocjacyjnej tablicy
- 29. Odpowiednik Rubiego do C#? Operator
- 30. C# Uri.EscapeDatastring() odpowiednik dla Javy
Preferowany przez kogo? – user51568
Preferowane przez wydajność i zgodność ... –
nie jest sprawiedliwe pytanie "instanceof - w jakim języku?" – mysticcoder