Reputation: 735
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
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