সি ++ জাভা এর উদাহরণের সমতুল্য


202

জাভা এর সমমানের সি ++ অর্জন করার জন্য পছন্দসই পদ্ধতিটি কী instanceof?


57
কর্মক্ষমতা এবং সামঞ্জস্যের দ্বারা পছন্দসই ...
যুবাল অ্যাডাম

7
"উদাহরণস্বরূপ - কোন ভাষায়" জিজ্ঞাসা করা কি ন্যায়সঙ্গত নয়?
মাইস্টিকোডার

3
@ মাইস্টিকোডার: আমি বুলগেরিয়ানের জন্য "на на" পাই, জিটি যদিও সি ++ সমর্থন করে না
মার্ক কে কোয়ান

উত্তর:


200

ব্যবহার করার চেষ্টা করুন:

if(NewType* v = dynamic_cast<NewType*>(old)) {
   // old was safely casted to NewType
   v->doSomething();
}

এটির জন্য আপনার সংকলকটির আরটিটি সমর্থন সক্ষম হওয়া দরকার।

সম্পাদনা: আমি এই উত্তরে কিছু ভাল মন্তব্য ছিল!

প্রতিবার যখন আপনার একটি ডায়নামিক_কাস্ট ব্যবহার করার প্রয়োজন হয় (বা উদাহরণস্বরূপ) আপনি নিজের কাছে এটি প্রয়োজনীয় জিনিস কিনা তা আরও ভালভাবে জিজ্ঞাসা করতে পারেন। এটি সাধারণত দুর্বল ডিজাইনের লক্ষণ।

সাধারণ ক্লাসআউন্ডগুলি বেস ক্লাসে ভার্চুয়াল ফাংশনটির জন্য আপনি যে শ্রেণীর জন্য যাচাই করছেন তার জন্য বিশেষ আচরণ স্থাপন করছেন বা সম্ভবত কোনও দর্শকের মতো এমন কিছু উপস্থাপন করছেন যেখানে আপনি ইন্টারফেস পরিবর্তন না করে সাবক্লাসের জন্য নির্দিষ্ট আচরণের পরিচয় দিতে পারেন (এর ভিজিটর গ্রহণযোগ্যতা ইন্টারফেস যোগ করা ব্যতীত) অবশ্যই)।

নির্দেশিত হিসাবে ডায়নামিক_কাস্ট বিনামূল্যে আসে না। একটি সাধারণ এবং ধারাবাহিকভাবে সম্পাদনকারী হ্যাক যা বেশিরভাগ হ্যান্ডেল করে (তবে সমস্ত ক্ষেত্রে নয়) মূলত আপনার শ্রেণীর যে সমস্ত সম্ভাব্য ধরণের সম্ভাব্য প্রকারের প্রতিনিধিত্ব করে এমন একটি এনাম যুক্ত করছে এবং আপনি সঠিকটি পেয়েছেন কিনা তা যাচাই করে।

if(old->getType() == BOX) {
   Box* box = static_cast<Box*>(old);
   // Do something box specific
}

এটি ওও ডিজাইনের পক্ষে ভাল নয়, তবে এটি কার্যকর হতে পারে এবং এর ব্যয় কম-বেশি কেবল একটি ভার্চুয়াল ফাংশন কল। এটি আরটিটিআই সক্ষম কিনা তা নির্বিশেষেও এটি কাজ করে।

মনে রাখবেন যে এই পদ্ধতিটি একাধিক স্তরের উত্তরাধিকারকে সমর্থন করে না তাই আপনি যদি সতর্ক না হন তবে আপনি কোডটির মতো দেখতে শেষ হতে পারেন:

// 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
}

4
আপনি যখন "উদাহরণস্বরূপ" চেক করেন তখন সাধারণত এটি হয়
লেসারালালান

7
আপনার যদি উদাহরণস্বরূপ ব্যবহার করতে হয় তবে বেশিরভাগ ক্ষেত্রে আপনার ডিজাইনে কিছু ভুল আছে।
মিস্লট

24
ভুলে যাবেন না যে ডায়নামিক_কাস্ট বড় ব্যয় সহ একটি অপারেশন।
ক্লাইম

13
গতিশীল ধরণের পরীক্ষার যুক্তিসঙ্গত ব্যবহারের অনেকগুলি উদাহরণ রয়েছে। এটি সাধারণত পছন্দ হয় না, তবে এটির একটি জায়গা রয়েছে। (অন্যথায়, কেন এটি বা এর সমতুল্য প্রতিটি বড় OO- ভাষায় প্রদর্শিত হবে: সি ++, জাভা, পাইথন ইত্যাদি?)
পল ড্রাগার

2
আমি যদি উভয়কে আলাদাভাবে পরিচালনা করার প্রয়োজন না হয় তবে আমি উভয়ই আইওএক্সেপশন পর্যায়ে ধরতে পারি। যদি সেগুলি আলাদাভাবে পরিচালনা করা দরকার হয় তবে আমি প্রতিটি ব্যতিক্রমের জন্য একটি ক্যাচ ব্লক যুক্ত করব।
এম্লস্লট

37

আপনি যা করতে চান তার উপর নির্ভর করে আপনি এটি করতে পারেন:

template<typename Base, typename T>
inline bool instanceof(const T*) {
    return std::is_base_of<Base, T>::value;
}

ব্যবহার করুন:

if (instanceof<BaseClass>(ptr)) { ... }

তবে, এটি সংকলক দ্বারা পরিচিত হিসাবে প্রকারে পরিচালনা করে।

সম্পাদনা:

এই কোডটি পলিমারফিক পয়েন্টারগুলির জন্য কাজ করা উচিত:

template<typename Base, typename T>
inline bool instanceof(const T *ptr) {
    return dynamic_cast<const Base*>(ptr) != nullptr;
}

উদাহরণ: http://cpp.sh/6qir


মার্জিত এবং ভাল সম্পন্ন সমাধান। +1 তবে সঠিক পয়েন্টারটি পেতে সতর্ক হন। পলিমারফিক পয়েন্টারের জন্য বৈধ নয়?
অ্যাড্রিয়ান মাইয়ার

এই ফাংশনটি ব্যবহার করার সময় আমরা যদি পয়েন্টারকে সম্মান করি? এটি কি তখন বহুতল পয়েন্টারগুলির জন্য কাজ করবে?
চিহ্নিত.কডজিয়ারস্কি

এটি কেবল কম্পাইলার হিসাবে পরিচিত ধরণেরগুলিতেই পরিচালনা করে না। পলিমারফিক পয়েন্টারগুলির সাথে কাজ করবে না, আপনি ডিফের্নেস হন কিনা তা বিবেচনা করে না। আমি এমন কিছু যুক্ত করব যা সেই ক্ষেত্রে কার্যকর হতে পারে।
পানজী

2
আমি এই পদ্ধতির একটি সংস্করণ লিখতে আপনার উদাহরণটি সংশোধন করেছি যা পয়েন্টারের পরিবর্তে রেফারেন্স ব্যবহার করে: cpp.sh/8owv
শ্রী হর্ষ চিলকাপতি

গতিশীল castালাই "কনস্ট" এর টার্গেট ধরণের কেন?
ব্যবহারকারী 1056903

7

গতিশীল_কাস্ট ছাড়া ইনস্ট্যান্সের বাস্তবায়ন

আমি মনে করি এই প্রশ্নটি আজও প্রাসঙ্গিক। সি ++ 11 স্ট্যান্ডার্ড ব্যবহার করে আপনি এখন instanceofএটি ব্যবহার না করে কোনও ফাংশন বাস্তবায়ন করতে সক্ষম হন dynamic_cast:

if (dynamic_cast<B*>(aPtr) != nullptr) {
  // aPtr is instance of B
} else {
  // aPtr is NOT instance of B
}

তবে আপনি এখনও RTTIসমর্থনের উপর নির্ভরশীল । সুতরাং এখানে কিছু ম্যাক্রো এবং মেটাপ্রোগ্র্যামিং ম্যাজিকের উপর নির্ভর করে এই সমস্যার জন্য আমার সমাধান এখানে। একমাত্র ত্রুটি ইমো হ'ল এই পদ্ধতিটি একাধিক উত্তরাধিকারের জন্য কাজ করে না

InstanceOfMacros.h

#include <set>
#include <tuple>
#include <typeindex>

#define _EMPTY_BASE_TYPE_DECL() using BaseTypes = std::tuple<>;
#define _BASE_TYPE_DECL(Class, BaseClass) \
  using BaseTypes = decltype(std::tuple_cat(std::tuple<BaseClass>(), Class::BaseTypes()));
#define _INSTANCE_OF_DECL_BODY(Class)                                 \
  static const std::set<std::type_index> baseTypeContainer;           \
  virtual bool instanceOfHelper(const std::type_index &_tidx) {       \
    if (std::type_index(typeid(ThisType)) == _tidx) return true;      \
    if (std::tuple_size<BaseTypes>::value == 0) return false;         \
    return baseTypeContainer.find(_tidx) != baseTypeContainer.end();  \
  }                                                                   \
  template <typename... T>                                            \
  static std::set<std::type_index> getTypeIndexes(std::tuple<T...>) { \
    return std::set<std::type_index>{std::type_index(typeid(T))...};  \
  }

#define INSTANCE_OF_SUB_DECL(Class, BaseClass) \
 protected:                                    \
  using ThisType = Class;                      \
  _BASE_TYPE_DECL(Class, BaseClass)            \
  _INSTANCE_OF_DECL_BODY(Class)

#define INSTANCE_OF_BASE_DECL(Class)                                                    \
 protected:                                                                             \
  using ThisType = Class;                                                               \
  _EMPTY_BASE_TYPE_DECL()                                                               \
  _INSTANCE_OF_DECL_BODY(Class)                                                         \
 public:                                                                                \
  template <typename Of>                                                                \
  typename std::enable_if<std::is_base_of<Class, Of>::value, bool>::type instanceOf() { \
    return instanceOfHelper(std::type_index(typeid(Of)));                               \
  }

#define INSTANCE_OF_IMPL(Class) \
  const std::set<std::type_index> Class::baseTypeContainer = Class::getTypeIndexes(Class::BaseTypes());

ডেমো

তারপরে আপনি এই জিনিসগুলি ( সতর্কতার সাথে ) নীচের হিসাবে ব্যবহার করতে পারেন :

DemoClassHierarchy.hpp *

#include "InstanceOfMacros.h"

struct A {
  virtual ~A() {}
  INSTANCE_OF_BASE_DECL(A)
};
INSTANCE_OF_IMPL(A)

struct B : public A {
  virtual ~B() {}
  INSTANCE_OF_SUB_DECL(B, A)
};
INSTANCE_OF_IMPL(B)

struct C : public A {
  virtual ~C() {}
  INSTANCE_OF_SUB_DECL(C, A)
};
INSTANCE_OF_IMPL(C)

struct D : public C {
  virtual ~D() {}
  INSTANCE_OF_SUB_DECL(D, C)
};
INSTANCE_OF_IMPL(D)

নিম্নোক্ত কোডটি অযৌক্তিকভাবে সঠিক আচরণটি যাচাই করতে একটি ছোট ডেমো উপস্থাপন করে।

InstanceOfDemo.cpp

#include <iostream>
#include <memory>
#include "DemoClassHierarchy.hpp"

int main() {
  A *a2aPtr = new A;
  A *a2bPtr = new B;
  std::shared_ptr<A> a2cPtr(new C);
  C *c2dPtr = new D;
  std::unique_ptr<A> a2dPtr(new D);

  std::cout << "a2aPtr->instanceOf<A>(): expected=1, value=" << a2aPtr->instanceOf<A>() << std::endl;
  std::cout << "a2aPtr->instanceOf<B>(): expected=0, value=" << a2aPtr->instanceOf<B>() << std::endl;
  std::cout << "a2aPtr->instanceOf<C>(): expected=0, value=" << a2aPtr->instanceOf<C>() << std::endl;
  std::cout << "a2aPtr->instanceOf<D>(): expected=0, value=" << a2aPtr->instanceOf<D>() << std::endl;
  std::cout << std::endl;
  std::cout << "a2bPtr->instanceOf<A>(): expected=1, value=" << a2bPtr->instanceOf<A>() << std::endl;
  std::cout << "a2bPtr->instanceOf<B>(): expected=1, value=" << a2bPtr->instanceOf<B>() << std::endl;
  std::cout << "a2bPtr->instanceOf<C>(): expected=0, value=" << a2bPtr->instanceOf<C>() << std::endl;
  std::cout << "a2bPtr->instanceOf<D>(): expected=0, value=" << a2bPtr->instanceOf<D>() << std::endl;
  std::cout << std::endl;
  std::cout << "a2cPtr->instanceOf<A>(): expected=1, value=" << a2cPtr->instanceOf<A>() << std::endl;
  std::cout << "a2cPtr->instanceOf<B>(): expected=0, value=" << a2cPtr->instanceOf<B>() << std::endl;
  std::cout << "a2cPtr->instanceOf<C>(): expected=1, value=" << a2cPtr->instanceOf<C>() << std::endl;
  std::cout << "a2cPtr->instanceOf<D>(): expected=0, value=" << a2cPtr->instanceOf<D>() << std::endl;
  std::cout << std::endl;
  std::cout << "c2dPtr->instanceOf<A>(): expected=1, value=" << c2dPtr->instanceOf<A>() << std::endl;
  std::cout << "c2dPtr->instanceOf<B>(): expected=0, value=" << c2dPtr->instanceOf<B>() << std::endl;
  std::cout << "c2dPtr->instanceOf<C>(): expected=1, value=" << c2dPtr->instanceOf<C>() << std::endl;
  std::cout << "c2dPtr->instanceOf<D>(): expected=1, value=" << c2dPtr->instanceOf<D>() << std::endl;
  std::cout << std::endl;
  std::cout << "a2dPtr->instanceOf<A>(): expected=1, value=" << a2dPtr->instanceOf<A>() << std::endl;
  std::cout << "a2dPtr->instanceOf<B>(): expected=0, value=" << a2dPtr->instanceOf<B>() << std::endl;
  std::cout << "a2dPtr->instanceOf<C>(): expected=1, value=" << a2dPtr->instanceOf<C>() << std::endl;
  std::cout << "a2dPtr->instanceOf<D>(): expected=1, value=" << a2dPtr->instanceOf<D>() << std::endl;

  delete a2aPtr;
  delete a2bPtr;
  delete c2dPtr;

  return 0;
}

আউটপুট:

a2aPtr->instanceOf<A>(): expected=1, value=1
a2aPtr->instanceOf<B>(): expected=0, value=0
a2aPtr->instanceOf<C>(): expected=0, value=0
a2aPtr->instanceOf<D>(): expected=0, value=0

a2bPtr->instanceOf<A>(): expected=1, value=1
a2bPtr->instanceOf<B>(): expected=1, value=1
a2bPtr->instanceOf<C>(): expected=0, value=0
a2bPtr->instanceOf<D>(): expected=0, value=0

a2cPtr->instanceOf<A>(): expected=1, value=1
a2cPtr->instanceOf<B>(): expected=0, value=0
a2cPtr->instanceOf<C>(): expected=1, value=1
a2cPtr->instanceOf<D>(): expected=0, value=0

c2dPtr->instanceOf<A>(): expected=1, value=1
c2dPtr->instanceOf<B>(): expected=0, value=0
c2dPtr->instanceOf<C>(): expected=1, value=1
c2dPtr->instanceOf<D>(): expected=1, value=1

a2dPtr->instanceOf<A>(): expected=1, value=1
a2dPtr->instanceOf<B>(): expected=0, value=0
a2dPtr->instanceOf<C>(): expected=1, value=1
a2dPtr->instanceOf<D>(): expected=1, value=1

কর্মক্ষমতা

এখন সবচেয়ে আকর্ষণীয় প্রশ্নটি দেখা দেয়, যদি এই খারাপ জিনিসগুলি ব্যবহারের চেয়ে আরও দক্ষ হয় dynamic_cast। অতএব আমি একটি খুব প্রাথমিক পারফরম্যান্স পরিমাপ অ্যাপ্লিকেশন লিখেছি।

InstanceOfPerformance.cpp

#include <chrono>
#include <iostream>
#include <string>
#include "DemoClassHierarchy.hpp"

template <typename Base, typename Derived, typename Duration>
Duration instanceOfMeasurement(unsigned _loopCycles) {
  auto start = std::chrono::high_resolution_clock::now();
  volatile bool isInstanceOf = false;
  for (unsigned i = 0; i < _loopCycles; ++i) {
    Base *ptr = new Derived;
    isInstanceOf = ptr->template instanceOf<Derived>();
    delete ptr;
  }
  auto end = std::chrono::high_resolution_clock::now();
  return std::chrono::duration_cast<Duration>(end - start);
}

template <typename Base, typename Derived, typename Duration>
Duration dynamicCastMeasurement(unsigned _loopCycles) {
  auto start = std::chrono::high_resolution_clock::now();
  volatile bool isInstanceOf = false;
  for (unsigned i = 0; i < _loopCycles; ++i) {
    Base *ptr = new Derived;
    isInstanceOf = dynamic_cast<Derived *>(ptr) != nullptr;
    delete ptr;
  }
  auto end = std::chrono::high_resolution_clock::now();
  return std::chrono::duration_cast<Duration>(end - start);
}

int main() {
  unsigned testCycles = 10000000;
  std::string unit = " us";
  using DType = std::chrono::microseconds;

  std::cout << "InstanceOf performance(A->D)  : " << instanceOfMeasurement<A, D, DType>(testCycles).count() << unit
            << std::endl;
  std::cout << "InstanceOf performance(A->C)  : " << instanceOfMeasurement<A, C, DType>(testCycles).count() << unit
            << std::endl;
  std::cout << "InstanceOf performance(A->B)  : " << instanceOfMeasurement<A, B, DType>(testCycles).count() << unit
            << std::endl;
  std::cout << "InstanceOf performance(A->A)  : " << instanceOfMeasurement<A, A, DType>(testCycles).count() << unit
            << "\n"
            << std::endl;
  std::cout << "DynamicCast performance(A->D) : " << dynamicCastMeasurement<A, D, DType>(testCycles).count() << unit
            << std::endl;
  std::cout << "DynamicCast performance(A->C) : " << dynamicCastMeasurement<A, C, DType>(testCycles).count() << unit
            << std::endl;
  std::cout << "DynamicCast performance(A->B) : " << dynamicCastMeasurement<A, B, DType>(testCycles).count() << unit
            << std::endl;
  std::cout << "DynamicCast performance(A->A) : " << dynamicCastMeasurement<A, A, DType>(testCycles).count() << unit
            << "\n"
            << std::endl;
  return 0;
}

ফলাফলগুলি পৃথক হয় এবং মূলত সংকলক অপ্টিমাইজেশনের ডিগ্রির উপর ভিত্তি করে। g++ -std=c++11 -O0 -o instanceof-performance InstanceOfPerformance.cppআমার স্থানীয় মেশিনে আউটপুট ব্যবহার করে কর্মক্ষমতা পরিমাপের প্রোগ্রামটি সংকলন করা ছিল:

InstanceOf performance(A->D)  : 699638 us
InstanceOf performance(A->C)  : 642157 us
InstanceOf performance(A->B)  : 671399 us
InstanceOf performance(A->A)  : 626193 us

DynamicCast performance(A->D) : 754937 us
DynamicCast performance(A->C) : 706766 us
DynamicCast performance(A->B) : 751353 us
DynamicCast performance(A->A) : 676853 us

এই মুহূর্তে, এই ফলাফলটি খুব স্বচ্ছন্দ ছিল, কারণ সময়টি দেখায় যে পদ্ধতির তুলনায় নতুন পদ্ধতির খুব বেশি দ্রুত নয় dynamic_cast। এটি বিশেষ পরীক্ষার ক্ষেত্রে আরও কম দক্ষ যা কোন পয়েন্টারের Aউদাহরণ হিসাবে যদি পরীক্ষা করে Aকিন্তু কম্পাইলার অপটিমাইজেশন ব্যবহার করে আমাদের বাইনারি টিউন করে জোয়ার মোড় নেয়। সম্পর্কিত সংকলক কমান্ড হয় g++ -std=c++11 -O3 -o instanceof-performance InstanceOfPerformance.cpp। আমার স্থানীয় মেশিনে ফলাফলটি আশ্চর্যজনক ছিল:

InstanceOf performance(A->D)  : 3035 us
InstanceOf performance(A->C)  : 5030 us
InstanceOf performance(A->B)  : 5250 us
InstanceOf performance(A->A)  : 3021 us

DynamicCast performance(A->D) : 666903 us
DynamicCast performance(A->C) : 698567 us
DynamicCast performance(A->B) : 727368 us
DynamicCast performance(A->A) : 3098 us

আপনি যদি একাধিক উত্তরাধিকারের উপর নির্ভরশীল না হন তবে ভাল পুরানো সি ম্যাক্রোস, আরটিটিআই এবং টেমপ্লেট রূপকগুলির বিরোধী এবং আপনার শ্রেণিবৃত্তির শ্রেণিতে কিছু ছোট নির্দেশ যুক্ত করতে খুব অলস না হন, তবে এই পদ্ধতিটি আপনার প্রয়োগকে কিছুটা বাড়িয়ে তুলতে পারে যদি আপনি প্রায়শই কোনও পয়েন্টারের উদাহরণটি পরীক্ষা করে শেষ করেন তবে এর কার্যকারিতাটির প্রতি শ্রদ্ধা সহ। তবে সাবধানতার সাথে ব্যবহার করুন । এই পদ্ধতির নির্ভুলতার জন্য কোনও ওয়ারেন্টি নেই।

দ্রষ্টব্য: সমস্ত ডেমো clang (Apple LLVM version 9.0.0 (clang-900.0.39.2))ম্যাকবুক প্রো মিড 2012 তে ম্যাকওএস সিয়েরার অধীনে ব্যবহার করে সংকলিত হয়েছিল ।

সম্পাদনা: আমি লিনাক্স মেশিন ব্যবহার করে পারফরম্যান্সও পরীক্ষা করে দেখেছি gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609। এই প্ল্যাটফর্মে পারফোনেন্স সুবিধাটি ঝাঁকুনির সাথে থাকা ম্যাকওগুলির মতো তাত্পর্যপূর্ণ ছিল না।

আউটপুট (সংকলক অপ্টিমাইজেশন ছাড়াই):

InstanceOf performance(A->D)  : 390768 us
InstanceOf performance(A->C)  : 333994 us
InstanceOf performance(A->B)  : 334596 us
InstanceOf performance(A->A)  : 300959 us

DynamicCast performance(A->D) : 331942 us
DynamicCast performance(A->C) : 303715 us
DynamicCast performance(A->B) : 400262 us
DynamicCast performance(A->A) : 324942 us

আউটপুট (সংকলক অপ্টিমাইজেশান সহ):

InstanceOf performance(A->D)  : 209501 us
InstanceOf performance(A->C)  : 208727 us
InstanceOf performance(A->B)  : 207815 us
InstanceOf performance(A->A)  : 197953 us

DynamicCast performance(A->D) : 259417 us
DynamicCast performance(A->C) : 256203 us
DynamicCast performance(A->B) : 261202 us
DynamicCast performance(A->A) : 193535 us

ভাল চিন্তা-ভাবনা উত্তর! আমি আনন্দিত আপনি সময় সরবরাহ করেছেন। এটি একটি আকর্ষণীয় পড়া ছিল।
এরিক

0

dynamic_castঅদক্ষ বলে পরিচিত। এটা তোলে উত্তরাধিকার অনুক্রমের আপ ঘোরে, আর এটা একমাত্র সমাধান আপনি উত্তরাধিকার একাধিক মাত্রা আছে যদি, এবং যদি একটি বস্তু তার টাইপ শ্রেণীবিন্যাসে ধরনের যে কোনো একটি একটি দৃষ্টান্ত হল চেক করতে হবে।

তবে যদি এর কোনও আরও সীমিত ফর্মটি instanceofযদি পরীক্ষা করে থাকে যে কোনও বস্তু আপনার নির্দিষ্টভাবে নির্দিষ্ট করে দেয় তবে এটি আপনার প্রয়োজনের জন্য যথেষ্ট, নীচের ফাংশনটি অনেক বেশি দক্ষ হবে:

template<typename T, typename K>
inline bool isType(const K &k) {
    return typeid(T).hash_code() == typeid(k).hash_code();
}

আপনি উপরের ফাংশনটি কীভাবে আহ্বান করবেন তার উদাহরণ এখানে রয়েছে:

DerivedA k;
Base *p = &k;

cout << boolalpha << isType<DerivedA>(*p) << endl;  // true
cout << boolalpha << isType<DerivedB>(*p) << endl;  // false

আপনি টেমপ্লেট প্রকারটি নির্দিষ্ট করবেন A(যে ধরণের ধরণের জন্য আপনি যাচাই করছেন) এবং আপনি যে বস্তুটি পরীক্ষা করতে চান তা আর্গুমেন্ট হিসাবে পাস করবেন (কোন টেমপ্লেটের Kধরণটি অনুমান করা হবে)।


বিভিন্ন ধরণের জন্য স্ট্যান্ডার্ডটির জন্য হ্যাশ_কোডটি অনন্য হতে হবে না, সুতরাং এটি বিশ্বাসযোগ্য নয়।
mattnz

2
টাইপড (টি) নিজেই কি সমতার সাথে তুলনাযোগ্য নয়, তাই হ্যাশকোডের উপর কোনও নির্ভরতার প্রয়োজন নেই?
পল স্টেলিয়ান

-5
#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);
 }

1
এটি সত্যই খারাপ উদাহরণ। ওভারলোডিং কেন ব্যবহার করবেন না, তা সস্তা?
ব্যবহারকারী 1095108

11
মূল সমস্যাটি হ'ল এটি প্রশ্নের উত্তর দিতে ব্যর্থ। instanceofডায়নামিক টাইপের অনুসন্ধান করে তবে এই উত্তরে ডায়নামিক এবং স্ট্যাটিক টাইপ সর্বদা মিল থাকে।
এমসাল্টারস

@ এইচএইচএইচ আপনি উত্তরটি জিজ্ঞাসা করা প্রশ্ন বন্ধ উপায়!
প্রোগ্রামার

-11

এটি জিসিসি কমপ্লায়ার সহ কোড :: ব্লকস আইডিই ব্যবহার করে আমার পক্ষে নিখুঁত কাজ করেছে

#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;
}

1
@ প্রোগ্রামার আমার ধারণা আপনি @pgp কল করতে চেয়েছিলেন, আমি কেবল তার কোড ফর্ম্যাটিংটি ঠিক করেছি। এছাড়াও, তার উত্তরটি মূলত "ব্যবহার typeid" বলে মনে হয় , যা ভুল হওয়ার পরেও ("কোনও গ্যারান্টি নেই যে একই স্ট্যান্ড :: টাইপ_ইনফো উদাহরণটি একই ধরণের টাইপড এক্সপ্রেশনটির সমস্ত মূল্যায়ন দ্বারা উল্লেখ করা হবে ... assert(typeid(A) == typeid(A)); /* not guaranteed */", দেখুন সিপ্রেফারেন্স ডট কম ) নির্দেশ করে যে তিনি কমপক্ষে কার্যনির্বাহী উদাহরণ উপস্থাপন করতে অবহেলিত হওয়ায় তিনি যদি কমপক্ষে প্রশ্নটির উত্তর দেওয়ার চেষ্টা করেছিলেন।
আন্দ্রেস রিওফ্রিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.