I want to be able to nest a class within a class or a struct within a struct. The reason for doing so is that if i have a class, I usually like to have functions that test out functionality of that class, but I want to keep testing stuff separate from the actual class but still be part of it, so if I were to use the object it would look something like:
every tool has a purpose, but that said, most of the time the point of making a class is to reuse a block of code. If its buried inside something else, it is not reusable, or not as clean and easy. So you have to determine if putting it there serves a bigger, better purpose than being able to reuse the inner class's code someday.
> If its buried inside something else, it is not reusable, or not as clean and easy.
The member class (nested class) is public, so it is usable from any part of the program; as easily as any class declared within a namespace.
The name of a member class that is not public is not accessible everywhere, though there are no restrictions on accessing objects of that class type.
cppreference has this example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class enclose {
struct nested { // private member
void g() {}
};
public:
static nested f() { return nested{}; }
};
int main()
{
//enclose::nested n1 = enclose::f(); // error: 'nested' is private
enclose::f().g(); // OK: does not name 'nested'
auto n2 = enclose::f(); // OK: does not name 'nested'
n2.g();
}
True, that is a good example of the mechanics. This falls under my 'clean and easy' caveat ... its a little wonky with the public/private as you noted, and now to find the bits you need it is, at best, in the middle of something else.
I sadly can't even remember what problem nested classes resolve that can't be done by has-a or inheritance, though, so they seem like clutter without benefit... I know there is a reason but I am going to have to revisit that.
What do the testing frameworks do? Do they inject the Test class, or are they separate?
Is there a way of getting rid of all the testing stuff, once it is proven that the code works as intended? I mean it is easy enough to enclose the Test class with preprocessor #ifdef, but personally I would rather not see them at all in a post tested release build.
Are there any downsides to having a separate Test class that takes a user object as an argument?
> I sadly can't even remember what problem nested classes resolve that can't be done by has-a or inheritance
Nested classes minimise dependencies. For example, the iterator class for a list that can only be used in conjunction with the list class would be (should be) a nested class. In the standard library, iterators are usually member classes; std::ios_base::failure is a member class etc.
Just as in real life it is a mistake to demand that every possession one has must be reusable by all and sundry in the universe, so too in software. There are many classes that are designed for restricted use.
> What do the testing frameworks do? Do they inject the Test class, or are they separate?
The test code need not have to be a class; very often, functions are good enough.
Frameworks (or libraries) which support mock testing (for example, Typemock's Isolator++ or GoogleTest's Google Mock), mock (fake) objects that simulate the behaviour of the real ones on which the code is dependant are created and added to the test code.
> Is there a way of getting rid of all the testing stuff, once it is proven that the code works as intended?
This is what I tend to do:
Say, the component is a.cpp. Create a separate test driver, say a_test.cpp (Often, the test code or class may be granted a friend status to the class being tested.) Link them along with the stubs or mock dependencies into the test frame. In the production code build, there would not be any a_test.cpp or stubs.
> Are there any downsides to having a separate Test class that takes a user object as an argument?
No. This is actually a useful technique when the behaviour of an object under different states needs to be tested; put the object into the state to be tested and pass it to the test component (sometimes along with expected results).