C++嵌套类是正确的封装方法吗?

问题描述 投票:1回答:1

我有一个全局类 TRK 有许多成员和方法。我想通过将这些成员和方法分门别类来组织它们,例如 Fitting这样,主类的命名空间就不会过于拥挤。在一个完美的世界里,我希望这个例子能够成功。

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 类的构造函数,而我需要 TRK 构造函数也能自动实例化嵌套的类,如 Fitting嵌套类,对于该实例的 TRK. 然后,我需要能够将这些嵌套类的成员的值实例化,并在 TRK 构造函数。例如,如果 Fitting 有成员 x的值,我需要能够初始化 x 内的TRK实例。TRK 构造函数,给定该构造函数的参数。我不清楚的是,到底该如何去做;如何以及在哪里可以实例化这些嵌套类?

  2. 从TRK实例和方法中访问嵌套类的成员,反之亦然。我已经可以通过传递 TRK 通过引用嵌套类,如图所示,但我不知道如何做前者。

例如,我的方法是 Fitting 的成员,需要使用任何 TRK 的实例,该 Fitting 内创建的。同样,我也有方法 Fitting 的方法 TRK 需要能够调用。

我是否应该为此使用嵌套类?我试过使用命名空间和继承,但我无法让事情按照我想要的方式工作。我的核心问题是试图

c++ encapsulation
1个回答
1
投票

构造嵌套类的实例

如果你想让 TRK 以此来引起建 TRK::Fitting 变量的定义。TRK::Fitting 必须完全为它所知,一个正向声明是不够的。然而,一旦你这样做了,你就可以像平时一样对嵌套类的成员变量进行初始化。下面是一个例子。

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

    Fitting fitting;

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

让嵌套类访问父类

嵌套类只是一个普通的类,只是它的名字是嵌套的。它不会自动知道父类的非静态成员变量在哪里。一个简单的解决方案是为嵌套类提供一个对父类实例的引用,就像这样。

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 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);
    }
};

从父类中调用子类的成员函数是很容易的,如图所示。TRK::quux().

如果你想使用继承,并让基类能够调用派生类中的函数,那么就可以使用 怪模怪样 可以使用,像这样。

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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.