第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

C ++相當(dāng)于instanceof

C ++相當(dāng)于instanceof

C++
紅顏莎娜 2019-08-12 17:07:22
C ++相當(dāng)于instanceof實(shí)現(xiàn)C ++等價(jià)的首選方法是instanceof什么?
查看完整描述

3 回答

?
Cats萌萌

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超9個(gè)贊

嘗試使用:


if(NewType* v = dynamic_cast<NewType*>(old)) {

   // old was safely casted to NewType

   v->doSomething();

}

這要求您的編譯器啟用rtti支持。


編輯:我對(duì)這個(gè)答案有一些好評(píng)!


每次你需要使用dynamic_cast(或instanceof)時(shí),你最好問問自己這是否是必要的。這通常是設(shè)計(jì)不佳的標(biāo)志。


典型的解決方法是將要檢查的類的特殊行為放入基類的虛函數(shù)中,或者引入類似訪問者的內(nèi)容,您可以在不改變界面的情況下為子類引入特定行為(除了添加訪問者接受接口)課程)。


正如所指出的,dynamic_cast不是免費(fèi)的。處理大多數(shù)(但不是所有情況)的簡(jiǎn)單且始終如一的執(zhí)行hack基本上是添加一個(gè)枚舉,表示您的類可以擁有的所有可能類型,并檢查您是否擁有正確的類型。


if(old->getType() == BOX) {

   Box* box = static_cast<Box*>(old);

   // Do something box specific

}

這不是好設(shè)計(jì),但它可以是一種解決方法,其成本或多或少只是虛擬函數(shù)調(diào)用。無(wú)論是否啟用RTTI,它都可以工作。


請(qǐng)注意,此方法不支持多級(jí)繼承,因此如果您不小心,可能會(huì)以如下代碼結(jié)束:


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

}


查看完整回答
反對(duì) 回復(fù) 2019-08-12
?
搖曳的薔薇

TA貢獻(xiàn)1793條經(jīng)驗(yàn) 獲得超6個(gè)贊


沒有dynamic_cast的實(shí)現(xiàn)實(shí)例

我認(rèn)為這個(gè)問題今天仍然有用。使用C ++ 11標(biāo)準(zhǔn),您現(xiàn)在可以實(shí)現(xiàn)一個(gè)instanceof函數(shù)而不使用dynamic_cast這樣的:


if (dynamic_cast<B*>(aPtr) != nullptr) {

  // aPtr is instance of B

} else {

  // aPtr is NOT instance of B

}

但你依然依賴RTTI支持。所以這是我的解決方案,取決于一些宏和Metaprogramming魔術(shù)。唯一的缺點(diǎn)是恕我直言,這種做法并沒有對(duì)工作的多重繼承。


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());

演示

然后你可以使用這些東西(謹(jǐn)慎),如下所示:


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)

以下代碼提供了一個(gè)小型演示,用于驗(yàn)證基本的正確行為。


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

性能

現(xiàn)在出現(xiàn)的最有趣的問題是,如果這種邪惡的東西比使用它更有效dynamic_cast。因此,我寫了一個(gè)非?;镜男阅軠y(cè)量應(yīng)用程序。


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;

}

結(jié)果各不相同,主要基于編譯器優(yōu)化的程度。使用g++ -std=c++11 -O0 -o instanceof-performance InstanceOfPerformance.cpp本地計(jì)算機(jī)上的輸出編譯性能測(cè)量程序是:


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

嗯,這個(gè)結(jié)果非常清醒,因?yàn)闀r(shí)間表明新方法與dynamic_cast方法相比并不快。對(duì)于測(cè)試指針A是否是實(shí)例的特殊測(cè)試用例來(lái)說(shuō)效率更低A。但是,通過(guò)使用編譯器otpimization調(diào)整我們的二進(jìn)制來(lái)轉(zhuǎn)變趨勢(shì)。相應(yīng)的編譯器命令是g++ -std=c++11 -O3 -o instanceof-performance InstanceOfPerformance.cpp。在我的本地機(jī)器上的結(jié)果是驚人的:


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

如果你不依賴于多重繼承,不是好舊的C宏,RTTI和模板元編程的對(duì)手,并且不太懶于在類層次結(jié)構(gòu)的類中添加一些小指令,那么這種方法可以提升你的應(yīng)用程序一點(diǎn)點(diǎn)關(guān)于它的性能,如果你經(jīng)常最終檢查指針的實(shí)例。但要謹(jǐn)慎使用它。這種方法的正確性無(wú)法保證。


注意:所有演示都是clang (Apple LLVM version 9.0.0 (clang-900.0.39.2))在MacBook Pro Mid 2012上使用macOS Sierra 編譯的。


編輯: 我還測(cè)試了Linux機(jī)器上的性能gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609。在這個(gè)平臺(tái)上,性能優(yōu)勢(shì)并不像具有鏗鏘聲的macOs那么重要。


輸出(無(wú)編譯器優(yōu)化):


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

輸出(帶編譯器優(yōu)化):


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


查看完整回答
反對(duì) 回復(fù) 2019-08-12
  • 3 回答
  • 0 關(guān)注
  • 966 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)