The operator[]
that you defined for your TestClass
is in no way "inherited" or somehow "embedded" in your nested class.
You can think of C++ nested classes as just ordinary classes, that live in a "nested namespace": TestClass::NestedClass
in your sample code.
If you want an operator[]
for your nested class, you have to define one from scratch (as you did for your TestClass
).
EDIT 1: Returning Classes (C++ Is Not Java)
Note also that C++ is not like e.g. Java (with a pattern of allocating instances of classes with new
, and relying on a garbage collector to automatically collect "garbage").
So, code like this:
NestedClass newNestedClass(void) {
return new NestedClass();
}
should not even compile.
If you returned a NestedClass
instance dynamically allocated with new
, you should return a pointer to it, e.g.:
// Note the "*" for the returned pointer
NestedClass* newNestedClass() {
return new NestedClass();
}
But, this is more of a Java pattern.
In C++, you may just want to return an instance of NestedClass without a new
dynamic allocation; this should work just fine:
NestedClass newNestedClass() {
return NestedClass();
}
EDIT 2: Proper Resource Management
Note also that you may want to make the T* data;
member private
for better encapsulation and information hiding. You are providing proper public accessors (like operator[]
overloads) to access your class's data: expose the accessor member functions, not the data members.
Moreover, you dynamically allocated data
on the heap using new
. You must release the dynamically heap-allocated memory, to avoid memory (and resource) leaks.
A good place to do that is your class destructor, e.g.:
class TestClass {
private:
T* data;
public:
...
~TestClass() {
// Release resoruces dynamically allocated
delete data;
}
}
Note also that this code:
data = new T{t};
just dynamically allocates a single instance of T
, initializing it to the value t
.
The corresponding cleanup code is:
delete data;
However, if you want to dynamically allocate an array of T
s, the syntax is:
data = new T[elementCount];
// ... initialize data to some value...
and the corresponding cleanup syntax is:
delete[] data; // Note the []!!
Note also that, if you want to manually manage resources in your class, you should consider also defining copy constructor and copy assignment operator=()
(see the so called Rule of Three); and if you want to implement move semantics, you should also consider implementing move constructor and move assignment (in this case there's a corresponding "Rule of 5").
But if you rely on already available RAII resource managers, like std::vector
, you don't have to spend time, energy, and bug hunting, managing resources manually: it's all automatically managed by std::vector
, or whatever container class you choose (in this case, you have a simple "Rule of Zero" :) i.e. the default compiler-generated copy constructor, copy assignment operator, move constructor, move assignment operator and destructor will do the tight thing.
But, of course, if this is a learning excercise, you may want to implement those special member functions by yourself.