SORU
12 ŞUBAT 2010, Cuma


dynamic_cast ve C static_cast

C dynamic_cast anahtar kelime ile karıştı oldukça .

struct A {
    virtual void f() { }
  };
  struct B : public A { };
  struct C { };

  void f () {
    A a;
    B b;

    A* ap = &b;
    B* b1 = dynamic_cast<B*> (&a);  // NULL, because 'a' is not a 'B'
    B* b2 = dynamic_cast<B*> (ap);  // 'b'
    C* c = dynamic_cast<C*> (ap);   // NULL.

    A& ar = dynamic_cast<A&> (*ap); // Ok.
    B& br = dynamic_cast<B&> (*ap); // Ok.
    C& cr = dynamic_cast<C&> (*ap); // std::bad_cast
  }

tanım diyor ki:

dynamic_cast anahtar kelime bir gösterici ya da referans bir veri atmalarını başka bir tip, bir çalışma zamanı denetimi döküm geçerliliğini sağlamak için çalışıyor

Daha iyi şeyleri anlamak o C C dynamic_cast yaklaşık yazabilir miyiz?

CEVAP
12 ŞUBAT 2010, Cuma


Özellikle işaretçileri ilgili işte static_cast<> dynamic_cast<> bir özet. Bu 101 düzey bir döküm, tüm inceliklerini kapsamaz.

static_cast< Tür* >(Ao)

Bu ptr işaretçi alır ve güvenle türü bir işaretçi Type* atmak çalışır. Bu döküm derleme zamanında yapılır. Yalnızca yazın türleri ile ilgili ise dökme konser verecek. Eğer bu tür ilişkili değilse, derleyici bir hata iletisi alır. Örneğin:

class B {};
class D : public B {};
class X {};

int main()
{
  D* d = new D;
  B* b = static_cast<B*>(d); // this works
  X* x = static_cast<X*>(d); // ERROR - Won't compile
  return 0;
}

dynamic_cast< Tür* >(Ao)

Bu yine ptr işaretçiyi almaya çalışır ve güvenli bir şekilde yazın bir gösterici Type* koyun. Ama bu dökme zamanı değil, derleme zamanında yürütülür. Bu çalışma zamanı kast olduğu için, özellikle polimorfik sınıfları ile birlikte kullanıldığında yararlıdır. Bazı durumlarda sınıflar aslındagerekircast yasal olması için polimorfik olabilir.

İki yönden: bir adet gidebilirsiniz atmalarını (B2D) veya baz (D2B) türetilmiş. base için türetilmiş Nasıl D2B atmalarını zamanında işe yarayacağını görmek için yeteri kadar basit. Ya ptr Type elde edildi ya da değildi. D2B dynamic_cast<^ durumda . s, kurallar basit. Başka bir şey için bir şey fırlatmak için deneyebilirsiniz, ve eğer ptr aslında Type den türetilmiş Type* işaretçi dynamic_cast geri alacaksın. Aksi halde, BOŞ bir işaretçi elde edersiniz.

Ama B2D biraz daha karmaşık atmalarını. Aşağıdaki kodu göz önünde bulundurun:

#include <iostream>
using namespace std;

class Base
{
public:
    virtual void DoIt() = 0;    // pure virtual
    virtual ~Base() {};
};

class Foo : public Base
{
public:
    virtual void DoIt() { cout << "Foo"; }; 
    void FooIt() { cout << "Fooing It..."; }
};

class Bar : public Base
{
public :
    virtual void DoIt() { cout << "Bar"; }
    void BarIt() { cout << "baring It..."; }
};

Base* CreateRandom()
{
    if( (rand()%2) == 0 )
        return new Foo;
    else
        return new Bar;
}


int main()
{
    for( int n = 0; n < 10;   n )
    {
        Base* base = CreateRandom();

            base->DoIt();

        Bar* bar = (Bar*)base;
        bar->BarIt();
    }
  return 0;
}

() ana tür CreateRandom nesnenin ne olduğunu söyleyebilir mi() C-tarzı* bar Bar = cast (Bar*)taban; kesinlikle tip-güvenli değil dönecektir. Bunu nasıl tamir EDEBİLİR MİSİN? Bir şekilde bool gibi bir fonksiyonu AreYouABar() const = 0; temel sınıf Ekle Bar Foo false true iade etmek olacaktır. Ama başka bir yol daha var: dynamic_cast<> kullanın:

int main()
{
    for( int n = 0; n < 10;   n )
    {
        Base* base = CreateRandom();

        base->DoIt();

        Bar* bar = dynamic_cast<Bar*>(base);
        Foo* foo = dynamic_cast<Foo*>(base);
        if( bar )
            bar->BarIt();
        if( foo )
            foo->FooIt();
    }
  return 0;

}

Bu çalışma zamanında yürütmek atmalarını ve nesne (şimdilik hakkında endişelenmenize gerek yok) sorgulama, eğer soran aradığımız tip. Eğer öyle ise, dynamic_cast<Type*> bir işaretçi döndürür; aksi halde NULL döndürüyor.

Bu türetilmiş Bankası için döküm dynamic_cast<>, Taban, Foo ve Bar kullanarak Standart dediği olmalıpolimorfik tür. Polimorfik bir tür olabilmek için, sınıfınızın en az bir virtual işlevi olmalı. Eğer derslerin polimorfik tip değilse, dynamic_cast temel-türetilmiş kullanın derlenir değil. Örnek:

class Base {};
class Der : public Base {};


int main()
{
    Base* base = new Der;
    Der* der = dynamic_cast<Der*>(base); // ERROR - Won't compile

    return 0;
}

Sanal bir dtor gibi temel sanal fonksiyon, hem de Temel ve Der polimorfik tür yapacaktır eklemek için:

class Base 
{
public:
    virtual ~Base(){};
};
class Der : public Base {};


int main()
{
    Base* base = new Der;
    Der* der = dynamic_cast<Der*>(base); // OK

    return 0;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Eric Magidson

    Eric Magidso

    4 Ocak 2009
  • Justin Case

    Justin Case

    3 EKİM 2011
  • Smith Micro Graphics

    Smith Micro

    15 Mayıs 2008