C ++只能由另一个类使用的类

时间:2010-12-20 15:45:17

标签: c++ class nested-class

我正在构建一个类(A类),它需要能够在其操作过程中创建另一个类(B类)的多个实例,但是B类仅由几个成员函数使用。 A级,从未在课堂外使用过。如何最好地定义B类?将其变成A级私人会员是否实际/合理?这是嵌套类的预期目的,还是我与构造的精神分离?

谢谢, 悦

编辑:在进一步考虑时,我并不是在询问最佳实践,因为这是针对个人项目的。我希望从封装的角度将B类作为A类成员包含在内 - 完全从属的类实际上应该是其拥有类的一部分似乎是合理的。

我想知道这是否是嵌套类的合理用例?如果没有,嵌套类的目的是什么?

6 个答案:

答案 0 :(得分:3)

一种可能性是在您放置类的命名空间内定义名为detail的命名空间。 e.g。

// public_namespace_detail.hpp
namespace public_namespace
{
    namespace detail
    {
        class B
        {
          ...
        };

    }
}

// public_namespace.hpp
#include "public_namespace_detail.hpp"

namespace public_namespace
{
    class A
    {
       detail::B b;
       ...       
    };
}

答案 1 :(得分:2)

我只会让class Bclass A完全无关 - 如果没有别的话,如果您可以测试class Aclass B,那么就可以更轻松地编写测试分别。如果您不想走这条路线,请阻止任何人通过定义class B来实例化除class A之外的class B,使其拥有私有构造函数,然后使class A成为friend {{1}}。

答案 2 :(得分:1)

您有多种选择:

  1. 私人继承: class A : private B {};

  2. 嵌套课程: class A { class B { /* etc */ }; };

  3. 来自班级 A class A { B b; };
  4. B 的私人会员

    如果您100%确定在外面不需要,我个人会选择嵌套课程。

答案 3 :(得分:0)

对我来说,一般的经验法则是,如果我发现我有一个难以继承的问题,那么我可能会以错误的方式看待问题。

有没有办法可以重构你的程序,所以类不那么“耦合”? I.E.你能把这些函数移出A类引用B类(并把它们放在B中)吗?

答案 4 :(得分:0)

我会将它移到B之外,否则它将通过A的头文件(无论你喜不喜欢)暴露给其他类。换句话说,如果你改变B的实现,那么A的客户必须重新编译 - 因为B是在A中声明的。

我的项目结构应该清楚说明B的头文件不应该被其他类使用。例如,我有一个名为“exports”的文件夹,其中我放置了我打算在项目外共享的所有头文件。显然在那里找不到B的标题。

在不使用头文件的其他语言中,例如C#,如果B相当小,我将随意将B放在A中 - 可能不超过6-10行声明。

答案 5 :(得分:0)

是的,这里的嵌套类很好。

请注意,为了保持代码的有序性,我不会将B的定义放在A中。代替:

class A
{
    class B;
};

class A::B
{
};

除此之外,这允许将类A::B的定义放在A的实现文件中。

编辑:由于关于嵌套类是否可以访问包含类的私有成员似乎存在一些混淆,我提供了一个代码片段来证明它确实存在:

class A
{
    int x;

    class B
    {
        int func(A* p) { return p->x; }
    };
};

Variant without inline definition of A::B, also accepted:

class A
{
    int x;

    class B;
};

class A::B
{
    int func(A* p) { return p->x; }
};
  • Comeau:接受(两种变体)
  

您的Comeau C / C ++测试结果如下   如下:

     

Comeau C / C ++ 4。3。10。1(2008年10月6日   对于ONLINE_EVALUATION_BETA2,请致电11:28:09   版权所有1988-2008 Comeau Computing。   版权所有。模式:严格   错误C ++ noC ++ 0x_extensions

     

在严格模式下,使用-tused,编译   成功了(但请记住,Comeau   在线编译器没有链接)。   使用C ++ 0x扩展编译   禁用。