YoonSeok OH
YoonSeok OH

Reputation: 735

Is it relevant to use nested struct?

I'm trying to define a class that has private struct and public struct.

Private struct is the struct that will only be used by the class (e.g. SNode), and I don't want it to be visible outside the class because I don't want it to be mistakenly used (e.g. new Node()). Thus, I reached to the idea to set it basically hidden.

Public struct is the struct that will be used outside (e.g. SKeyValuePair), and it will have a pointer to a SNode.

Code Example is below.

[Class Definition]

template <typename T>
class A
{
private:

    struct SNode
    {
        SNode* pParentNode;
        SNode* pLeftChildNode;
        SNode* pRightChildNode;

        ...
    };

public:

    A<T>()
    {
    }

    virtual ~A()
    {
    }

    struct SPair
    {
    private:
    public:

        SNode* pNode;
        unsigned long long ullKey;
        T value;

        ...
    };

    const SPair GetMinKeyPair()
    {
        return SPair(...);
    }

    const SPair GetNextMinKeyPair()
    {
        ...
        return SPair(...);
    }
    };

[Usage]

A a;
...
for (A::SPair pair = a.GetMinKeyPair(); pair.pNode != nullptr; pair = a.GetNextMinKeyPair())
{
    ...
}

Q1. I wonder if this kind of nested struct (which public struct containing private struct pointer) should be avoided for some reason I currently don't know.

Q2. If there are reasons, I wonder what they are.

Upvotes: 3

Views: 718

Answers (1)

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

In general, this is not a bad way to do business.

It keeps the name SNode<T> private when it doesn't need to be public. (Though, as aschepler noted in comments, be aware that the type itself can still be used in full via auto; accessibility affects only names.)

So this is quite a neat way to organise things, and I do personally make use of nested types.

However, since A is a class template, you're going to have a copy of SNode for each T that you use. That's just how templates work. This means more code and a larger executable. For that reason, you might consider the more conventional approach of just putting the utility types in a namespace instead. Does it really matter whether people try to use them outside of A<T>?

Upvotes: 5

Related Questions