SORU
31 Aralık 2010, Cuma


Neden bir C iç içe sınıfları kullanmak istiyorsunuz ?

Biri iç içe sınıflar anlayış kullanmak için bazı iyi kaynakları doğru beni işaret edebilir misiniz? Programlama İlkeleri gibi bazı malzemeler var ve bunları IBM Knowledge Center - Nested Classes gibi

Ama hala sorun amaçlarını anlamakta güçlük çekiyorum. Biri yardım edebilir mi?

CEVAP
31 Aralık 2010, Cuma


İç içe sınıflar normal sınıflar gibi, ama:

  • ek erişim kısıtlaması bir sınıf tanımı içinde tüm tanımlar gibi) var
  • onlarverilen ad kirleten yokörneğin genel ad. Eğer hissettiğin B sınıfı çok derinden bağlı Bir sınıf, ama nesneleri A ve B ille ilgili, o zaman istersin, B sınıfı için sadece erişilebilir üzerinden ölçüm sınıfı (olur olarak Bir Sınıf).

Bazı örnekler:

Halka iç içe sınıfın ilgili sınıf bir kapsam koymak için


Sınıf eşyaları Element toplama bir sınıf SomeSpecificCollection sahip olmak istediğinizi varsayalım. Sonra da:

  1. iki sınıf: SomeSpecificCollection Element -, adı kötü, çünkü "Eleman muhtemelen adını bir çatışma nedeni için" genel yeterli

  2. 10* *bir ad tanıtmak ve sınıflar someSpecificCollection::Collection someSpecificCollection::Element beyan ederim. Adı riski çatışma, ama daha ayrıntılı olabilir mi?

  3. iki küresel sınıfları SomeSpecificCollection ve küçük bir dezavantajı vardır, ama muhtemelen sorun yok SomeSpecificCollectionElement - ilan.

  4. iç içe sınıfının genel olarak sınıf SomeSpecificCollection Sınıf Element ilan. Sonra:

    • Eleman genel ad olarak herhangi bir ad clases riski yok
    • SomeSpecificCollection uygulama sadece 3. gibi görünüyor - aynı SomeSpecificCollection::Element - Element ve her yerde sevk ama daha net
    • bu sade ve basit olur "belirli bir koleksiyon öğesi" değil, "bir koleksiyon belirli bir eleman"
    • SomeSpecificCollection aynı zamanda bir sınıf olduğu görülmektedir.

Benim görüşüme göre, son versiyonu kesinlikle en kolay ve bu nedenle en iyi tasarım.

Bana stres izin - daha ayrıntılı adları ile iki küresel sınıflar yapmaktan büyük bir fark değil. Bu küçük bir ayrıntı sadece, ama kodu daha açık hale getirir ımho.

Sınıf kapsamı içinde başka bir kapsam tanıtımı


Bu typedef veya çeteleler tanıtımı için özellikle kullanışlıdır. Sadece bir kod örneği burada ilan edeceğim:

class Product {
public:
    enum ProductType {
        FANCY, AWESOME, USEFUL
    };
    enum ProductBoxType {
        BOX, BAG, CRATE
    };
    Product(ProductType t, ProductBoxType b, String name);

    // the rest of the class: fields, methods
};

O zaman arayacak:

Product p(Product::FANCY, Product::BOX);

Ama bakıldığında kod tamamlama önerileri Product:: genellikle tüm olası numaralandırma değerleri (KUTU, SÜSLÜ, SANDIK) listelenen ve kolay bir hata (C 0x. kesinlikle yazılmış çeteleler tür çözmek, ama neyse).

Ama bu çeteleler için ek kapsam yuvalanmış sınıfları kullanarak tanıtmak, şeyler gibi görünebilir:

class Product {
public:
    struct ProductType {
        enum Enum { FANCY, AWESOME, USEFUL };
    };
    struct ProductBoxType {
        enum Enum { BOX, BAG, CRATE };
    };
    Product(ProductType::Enum t, ProductBoxType::Enum b, String name);

    // the rest of the class: fields, methods
};

Çağrı gibi görünüyor:

Product p(Product::ProductType::FANCY, Product::ProductBoxType::BOX);

Sonra bir IDE Product::ProductType:: yazarak, istenilen kapsam sadece çeteleler önerdi. Bu da hata yapma riskini azaltır.

Tabii ki bu küçük sınıflar için gerekli olmayabilir, ama eğer bir çeteleler bir sürü varsa, o zaman işler istemci programcılar için daha kolay hale getirir.

Aynı şekilde, "hiç gerek yoktu." eğer bir şablon typedefs büyük bir demet, organize edebilirsin Yararlı bir desen bazen.

PİMPL deyimi


Bu PİMPL (Özel Uygulama için kısa) bir deyim başlığından bir sınıfın uygulama ayrıntılarını kaldırmak için yararlıdır. Bu derlenmesine sınıfları sınıf üstbilgi zaman "" başlığı değişiklikler. bölüm uygulanmasına bağlı olarak azaltacak

Genellikle iç içe geçmiş bir sınıf kullanılarak uygulanan bir şey

X y:

class X {
public:
    X();
    virtual ~X();
    void publicInterface();
    void publicInterface2();
private:
    struct Impl;
    std::unique_ptr<Impl> impl;
}

X.cpp:

#include "X.h"
#include <windows.h>

struct X::Impl {
    HWND hWnd; // this field is a part of the class, but no need to include windows.h in header
    // all private fields, methods go here

    void privateMethod(HWND wnd);
    void privateMethod();
};

X::X() : impl(new Impl()) {
    // ...
}

// and the rest of definitions go here

Bu ağır ve çirkin bir başlık dosyası (Winapı) olan tam sınıf tanımı, bir harici kütüphane türleri tanımlama ihtiyacı varsa özellikle kullanışlıdır. Eğer PİMPL kullanıyorsanız, .cpp Winapı özgü işlevsellik sadece herhangi alın ve asla .h ekleyebilirsiniz.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Howard Pinsky

    Howard Pinsk

    6 AĞUSTOS 2006
  • Liberator

    Liberator

    14 EYLÜL 2007
  • The CGBros

    The CGBros

    20 AĞUSTOS 2011