繁体   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