开发者

C++ a class to be used only by another class

I'm building a class (class A) which needs to be able to create a number of instances of another class (class B) in the course of its operation, but class B is only used by a few member functions of class A, and never used outside of the class. How should class B best be defined? Is it practical / reasonable to make it a private member of Class A? Is this the intended purpose of nested classes, or am I parting with the spirit of the construct?

Thanks, Wyatt

EDIT: On further consideration, I'm not really asking about best practice, as this is for a personal project. I want to include class B as a member of class A from an encapsulation standpoint - it just seems reasonable that a class which is wholly subordinate should in fact be a part of its ow开发者_如何学JAVAning class.

What I'm wondering is whether or not this is a reasonable use-case for nested classes? If not, what is the purpose of nested classes?


One possibility is to define a namespace called detail inside the namespace where you put your classes. 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;
       ...       
    };
}


I would just make class B completely unrelated to class A -- if nothing else, it's going to make it easier to write tests if you can test class A and class B separately. If you don't want to go that route, prevent anyone from instantiating class B except class A by defining class B, making it have a private constructor, and then making class A a friend.


You have multiple options :

  1. private inheritance : class A : private B {};

  2. nested class : class A { class B { /* etc */ }; };

  3. Good ol' private member to class B from class A : class A { B b; };

I personally would go with the nested class if you're 100% sure it's not needed outside.


A general rule of thumb for me is that if I find I have a difficult problem with inheritance then I've probably looked at the problem in the wrong way.

Is there a way you can restructure your program so the classes are less "coupled"? I.E. Can you move the functions out of class A that reference class B (and place them in B)?


I would move it outside of B, since otherwise it will be exposed to other classes via the header file of A (whether you like it or not). Said differently, if you change the implementation of B, then clients of A must recompile - since B was declared inside of A.

The structure of my project should make it clear that the header file for B, should not be used by other classes. For example, I have a folder called "exports" where I place all my header files that I intend to be shared outside the project. Obviously B's header won't be found there.

In a different language that does not use header files, such as C#, I will casually place B inside of A, if B is fairly small - perhaps not more than 6-10 lines of declaration.


Yes, a nested class is fine here.

Note that to keep the code organized, I wouldn't place the definition of B inside A. Instead:

class A
{
    class B;
};

class A::B
{
};

Among other things, this allows the definition of class A::B to be placed inside A's implementation file.

EDIT: Since there seems to be some confusion about whether a nested class gets access to the containing class's private members, I provide a code snippet to prove that it does:

class A
{
    int x;

    class B
    {
        int func(A* p) { return p->x; }
    };
};
  • GCC 4.3.4: Accepted.

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: Accepted (both variants)

Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors C++ noC++0x_extensions

In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link). Compiled with C++0x extensions DISabled.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜