亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么要在C ++中使用嵌套類?

為什么要在C ++中使用嵌套類?

C++
波斯汪 2019-11-22 11:04:48
有人可以將我引向一些不錯的資源來理解和使用嵌套類嗎?我有一些像《編程原理》之類的材料,以及諸如《IBM Knowledge Center-Nested Classes》之類的東西但是我仍然很難理解他們的目的。有人可以幫我嗎?
查看完整描述

3 回答

?
POPMUISE

TA貢獻1765條經驗 獲得超5個贊

嵌套類與常規類一樣,但是:


它們具有附加的訪問限制(就像類定義中的所有定義一樣),

它們不會污染給定的名稱空間,例如全局名稱空間。如果您認為B類與A類之間的聯系如此緊密,但是A和B的對象不一定相關聯,那么您可能希望僅通過對A類進行范圍界定來訪問B類(將其稱為A ::類)。

一些例子:


公開嵌套類以將其置于相關類的范圍內

假設您想擁有一個SomeSpecificCollection將聚集class對象的類Element。然后,您可以:


聲明兩個類:SomeSpecificCollection和Element-不好,因為名稱“ Element”足夠通用,可能導致名稱沖突


引入命名空間someSpecificCollection并聲明類someSpecificCollection::Collection和someSpecificCollection::Element。沒有名稱沖突的風險,但是它還能變得更加冗長嗎?


聲明兩個全局類SomeSpecificCollection和SomeSpecificCollectionElement-有一些小缺點,但可能還可以。


聲明全局類SomeSpecificCollection和Element作為其嵌套類的類。然后:


您不會冒任何名稱沖突的風險,因為Element不在全局名稱空間中,

在實現中,SomeSpecificCollection您將just Element,以及其他所有地方都稱為SomeSpecificCollection::Element-,看起來與3.相同,但更清楚

顯而易見,它是“特定集合的元素”,而不是“特定集合的元素”

可見這SomeSpecificCollection也是一個類。

我認為,最后一個變體肯定是最直觀,因此也是最好的設計。


讓我強調一下-與使兩個全局類具有更詳細的名稱沒有太大區別。它只是一個很小的細節,但是恕我直言,它使代碼更加清晰。


在類范圍內引入另一個范圍

這對于引入typedef或枚舉特別有用。我將在此處發布一個代碼示例:


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

};

然后一個將呼叫:


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

但是,在查看的代碼完成建議時Product::,通常會列出所有可能的枚舉值(BOX,FANCY,CRATE),并且在這里容易出錯(C ++ 0x的強類型枚舉可以解決該問題,但是沒關系)。


但是,如果您使用嵌套類為這些枚舉引入其他范圍,則情況可能看起來像:


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

};

然后,調用看起來像:


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

然后,通過輸入Product::ProductType::IDE,只能從建議的范圍中獲取枚舉。這也減少了犯錯的風險。


當然,對于小型類而言,這可能不是必需的,但是如果一個類有很多枚舉,那么對于客戶端程序員來說,事情變得更容易了。


同樣,如果需要,您可以在模板中“組織”一大堆typedef。有時這是一個有用的模式。


PIMPL成語

PIMPL(指向IMPLementation的指針的縮寫)是一種慣用法,可用于從標頭中刪除類的實現細節。每當頭的“實現”部分更改時,這都減少了根據類的頭重新編譯類的需求。


通常使用嵌套類來實現:


Xh:


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

如果完整的類定義需要某些外部庫中類型的定義,該外部庫具有沉重的或難看的頭文件(使用WinAPI),則此功能特別有用。如果使用PIMPL,則只能將任何特定于WinAPI的功能封裝在中,.cpp而永遠不要將其包括在內.h。


查看完整回答
反對 回復 2019-11-22
  • 3 回答
  • 0 關注
  • 688 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號