Should I be using nested classes here?

Hi

If I want a class A to have an object of type Class B but objects of type B cannot be instantiated outside of class A, is this best achieved by making class B a nested class of A?

If so, is it possible to declare B in B.h rather than in A.h (using something like a forward declaration of B in A)? I ask as I including the full declaration of B (even without the implementation) could make A much longer and the code a bit messy.

Thanks
Last edited on
"Best" I'd say is subjective. There might be reasons you want to separate them logically or in a code base (e.g. separate devs working on them).

Nested classes are a solution. An alternative is to use friend classes, but mark class B's constructor as private.
The classes can be separated into multiple files if desired.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Example program

class SecretClass {

  friend class ActualClass;

  private:
    SecretClass(int a)
    : alpha(a)
    {
        // welcome to the secret club
    }
    
    int alpha;
};

class ActualClass {
  public:
    ActualClass()
    : sc(42)
    {
           
    }
  private:
    SecretClass sc;
};

int main()
{
    ActualClass ac;
    //SecretClass sc(1729); // compiler error: SecretClass::SecretClass(int)' is private
}


PS: You can also #include a header file in the middle of the definition of a class. I don't usually see projects that do this, I just wanted to say it's possible. But unless done in some really restrictive manner, this won't prevent others from also #including the file.

include guards removed for brevity

secretclass.hpp
1
2
3
4
class SecretClass {
  public:
    SecretClass(int a) { }  
};


actualclass.hpp
1
2
3
4
5
6
7
8
9
10
11
12
class ActualClass {

  public:

    ActualClass()
    : sc(42) { }

private:
  #include "secretclass.hpp"
 
  SecretClass sc;
};


main.cpp
1
2
3
4
5
6
7
#include "actualclass.hpp"

int main()
{
    ActualClass ac;
    //SecretClass sc(42); // error
}


I have been told that if you call a namespace "detail" or perhaps "impl[ementation]", it implies that it is a implementation detail of the class. This allows a user to know that they shouldn't mess with it, but still gives them the option to, if they know what they're doing.
https://stackoverflow.com/questions/26546265/what-is-the-detail-namespace-commonly-used-for

(But in this instance, since you can't put namespaces inside classes, you couldn't do that #include hack above if you used a detail namespace around SecretClass.)

In my opinion, I suggest using the detail namespace instead of irreversibly hiding things from the user.
Last edited on
Topic archived. No new replies allowed.