簡體   English   中英

C++ 嵌套類是正確的封裝方法嗎?

[英]Are C++ nested classes the right approach for encapsulation?

我有一個具有許多成員和方法的全局 class TRK 我想通過將它們分類到不同的命名類別來組織它們,例如Fitting ,這樣主 class 的命名空間就不會過度擁擠。 在一個完美的世界里,我希望這個例子能夠工作:

class TRK
{
    public:
        // constructors
        TRK(...);
        ...
        TRK();
        ~TRK();


        // nested classes
        class Fitting;

        // and many other methods...


    private:
        ...
};

class TRK::Fitting
{
    public:
        // constructors/destructor
        TRK& trk;
        Fitting();
        ~Fitting();

        // and many other methods...


    private:
        ...

};

我需要的關鍵是能夠:

  1. 使用TRK類的構造函數之一實例化一些TRK object ,我需要TRK構造函數還能夠自動實例化隨附的嵌套類,例如Fitting ,用於TRK的實例。 然后,我需要能夠在TRK構造函數中為這些嵌套類的成員實例化/賦予值。 例如,如果Fitting有一些成員x ,我需要能夠在TRK構造函數中為該 TRK 實例初始化x的值,給定構造函數 arguments 。 我不清楚 go 到底是怎么回事; 我如何以及在哪里可以實例化這些嵌套類?

  2. 從 TRK 實例和方法訪問嵌套類的成員,反之亦然。 如圖所示,我已經可以通過引用嵌套類傳遞TRK來完成后者,但我不確定如何執行前者。

例如,我的Fitting方法需要使用在其中創建該Fitting實例的任何TRK實例的成員。 同樣,我有TRK方法需要能夠調用的Fitting方法。

我什至應該為此使用嵌套類嗎? 我嘗試使用命名空間和 inheritance 但我無法讓事情按照我想要的方式工作。 我的核心問題是嘗試

構造嵌套類的實例

如果想讓TRK的構造函數反過來構造一個TRK::Fitting變量,它必須完全知道TRK::Fitting的定義,前向聲明是不夠的。 但是,一旦這樣做,您就可以像往常一樣初始化嵌套 class 類型的成員變量。 這是一個例子:

class TRK {
    class Fitting {
        int x;
    public:
        Fitting(int x): x(x) {}
    };

    Fitting fitting;

public:
    TRK(int y): fitting(y) {}
};

讓嵌套類訪問父 class

一個嵌套的 class 只是一個普通的 class,只是它的名字是嵌套的。 它不會自動知道父級的非靜態成員變量在哪里。 一個簡單的解決方案是為嵌套 class 提供對父 class 實例的引用,如下所示:

class TRK {
    class Fitting {
        TRK &parent;
        int x;
    public:
        Fitting(TRK &parent, int x): parent(parent), x(x) {}

        void foo() {
            // Use something from the parent class
            parent.bar();
        }
    };

    Fitting fitting;

public:
    TRK(int y): fitting(*this, y) {}
    void bar() {}
};

另一種選擇是不在子 class 中存儲對父的引用,而是將對父的引用顯式傳遞給子 class 的每個成員 function:

class TRK {
    class Fitting {
        void foo(TRK &parent) {
            // Use something from the parent class
            parent.bar();
        }
    };

    Fitting fitting;

public:
    TRK(int y): fitting(y) {}
    void bar() {}
    void quux() {
        fitting.bar(*this);
    }
};

從父 class 調用子 class 的成員 function 很容易,如TRK::quux()所示。

如果你想使用 inheritance 並讓基礎 class 能夠調用派生的 class 中的函數,那么可以使用奇怪的重復模板模式,如下所示:

template <typename Derived>
class TRK {
    ...

    void bar() {}

    void quux() {
        // We need to static_cast<> ourself to get an object of type Derived
        static_cast<Derived>(*this)::foo();
    }
};

class Derived: TRK<Derived> {
    ...
    void foo() {
        // We can directly call any base class member functions here
        bar();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM