What are the pros and cons of using nested public C++ classes and enumerations? For example, suppose you have a class called printer, and this class also stores information on output trays, you could have:
class printer
{
public:
std::string name_;
enum TYPE
{
TYPE_LOCAL,
TYPE_NETWORK,
};
class output_tray
{
...
};
...
};
printer prn;
printer::TYPE type;
printer::output_tray tray;
Alternatively:
class printer
{
public:
std::string name_;
...
};
enum PRINTER_TYPE
{
PRINTER_TYPE_LOCAL,
PRINTER_TYPE_NETWORK,
};
class output_tray
{
...
};
printer prn;
PRINTER_TYPE type;
output_tray tray;
I can see the benefits of nesting private enums/classes, but when it comes to public ones, the office is split - it seems to be more of a style choice.
So, which do you prefer and why?
Nested classes
There are several side effects to classes nested inside classes that I usually consider flaws (if not pure antipatterns).
Let's imagine the following code :
class A
{
public :
class B { /* etc. */ } ;
// etc.
} ;
Or even:
class A
{
public :
class B ;
// etc.
} ;
class A::B
{
public :
// etc.
} ;
So:
Privilegied Access: A::B has privilegied access to all members of A (methods, variables, symbols, etc.), which weakens encapsulation
A's scope is candidate for symbol lookup: code from inside B will see all symbols from A as possible candidates for a symbol lookup, which can confuse the code
forward-declaration: There is no way to forward-declare A::B without giving a full declaration of A
Extensibility: It is impossible to add another class A::C unless you are owner of A
Code verbosity: putting classes into classes only makes headers larger. You can still separate this into multiple declarations, but there's no way to use namespace-like aliases, imports or usings.
As a conclusion, unless exceptions (e.g. the nested class is an intimate part of the nesting class... And even then...), I see no point in nested classes in normal code, as the flaws outweights by magnitudes the perceived advantages.
Furthermore, it smells as a clumsy attempt to simulate namespacing without using C++ namespaces.
On the pro-side, you isolate this code, and if private, make it unusable but from the "outside" class...
Nested enums
Pros: Everything.
Con: Nothing.
The fact is enum items will pollute the global scope:
// collision
enum Value { empty = 7, undefined, defined } ;
enum Glass { empty = 42, half, full } ;
// empty is from Value or Glass?
Ony by putting each enum in a different namespace/class will enable you to avoid this collision:
namespace Value { enum type { empty = 7, undefined, defined } ; }
namespace Glass { enum type { empty = 42, half, full } ; }
// Value::type e = Value::empty ;
// Glass::type f = Glass::empty ;
Note that C++0x defined the class enum:
enum class Value { empty, undefined, defined } ;
enum class Glass { empty, half, full } ;
// Value e = Value::empty ;
// Glass f = Glass::empty ;
exactly for this kind of problems.
One con that can become a big deal for large projects is that it is impossible to make a forward declaration for nested classes or enums.
If you're never going to be using the dependent class for anything but working with the independent class's implementations, nested classes are fine, in my opinion.
It's when you want to be using the "internal" class as an object in its own right that things can start getting a little manky and you have to start writing extractor/inserter routines. Not a pretty situation.
It seems like you should be using namespaces instead of classes to group like things that are related to each other in this way. One con that I could see in doing nested classes is you end up with a really large source file that could be hard to grok when you are searching for a section.
There are no pros and cons per se of using nested public C++ classes. There are only facts. Those facts are mandated by the C++ standard. Whether a fact about nested public C++ classes is a pro or a con depends on the particular problem that you are trying to solve. The example you have given does not allow a judgement about whether nested classes are appropriate or not.
One fact about nested classes is, that they have privileged access to all members of the class that they belong to. This is a con, if the nested classes does not need such access. But if the nested class does not need such access, then it should not have been declared as a nested class. There are situations, when a class A wants to grant privileged access to certain other classes B. There are three solutions to this problem
Make B a friend of A
Make B a nested class of A
Make the methods and attributes, that B needs, public members of A.
In this situation, it's #3 that violates encapsulation, because A has control over his friends and over his nested classes, but not over classes that call his public methods or access his public attributes.
Another fact about nested classes is, that it is impossible to add another class A::C as a nested class of A unless you are owner of A. However, this is perfectly reasonable, because nested classes have privileged access. If it were possible to add A::C as a nested class of A, then A::C could trick A into granting access to privileged information; and that yould violate encapsulation. It's basically the same as with the friend declaration: the friend declaration does not grant you any special privileges, that your friend is hiding from others; it allows your friends to access information that you are hiding from your non-friends. In C++, calling someone a friend is an altruistic act, not an egoistic one. The same holds for allowing a class to be a nested class.
Som other facts about nested public classes:
A's scope is candidate for symbol lookup of B: If you don't want this, make B a friend of A instead of a nested class. However, there are cases where you want exactly this kind of symbol lookup.
A::B cannot be forward-declared: A and A::B are tightly coupled. Being able to use A::B without knowing A would only hide this fact.
To summarize this: if the tool does not fit your needs, don't blame the tool; blame yourself for using the tool; others might have different problems, for which the tool is perfect.
paercebal said everything I would say about nested enums.
WRT nested classes, my common and almost sole use case for them is when I have a class which is manipulating a specific type of resource, and I need a data class which represents something specific to that resource. In your case, output_tray might be a good example, but I don't generally use nested classes if the class is going to have any methods which are going to be called from outside the containing class, or is more than primarily a data class. I generally also don't nest data classes unless the contained class is not ever directly referenced outside the containing class.
So, for example, if I had a printer_manipulator class, it might have a contained class for printer manipulation errors, but printer itself would be a non-contained class.
Hope this helps. :)
Remember that you can always promote a nested class to a top-level one later, but you may not be able to do the opposite without breaking existing code. Therefore, my advice would be make it a nested class first, and if it starts to become a problem, make it a top-level class in the next version.
For me a big con to having it outside is that it becomes part of the global namespace. If the enum or related class only really applies to the class that it's in, then it makes sense. So in the printer case, everything that includes the printer will know about having full access to the enum PRINTER_TYPE, where it doesn't really need to know about it. I can't say i've ever used an internal class, but for an enum, this seems more logical to keep it inside. As another poster has pointed out, it's also a good idea to to use namespaces to group similar items, since clogging the global namespace can really be a bad thing. I have previously worked on projects which are massive and just bringing up an auto complete list on the global namespace takes 20 minutes. In my opinion nested enums and namespaced classes/structs are probably the cleanest approach.
I agree with the posts advocating for embedding your enum in a class but there are cases where it makes more sense to not do that (but please, at least put it in a namespace). If multiple classes are utilizing an enum defined within a different class, then those classes are directly dependent on that other concrete class (that owns the enum). That surely represents a design flaw since that class will be responsible for that enum as well as other responsibilities.
So, yeah, embed the enum in a class if other code only uses that enum to interface directly with that concrete class. Otherwise, find a better place to keep the enum such as a namespace.
If you put the enum into a class or a namespace, intellisense will be able to give you guidance when you're trying to remember the enum names. A small thing for sure, but sometimes the small things matter.
Visual Studio 2008 does not seem to be able to provide intellisense for nested classes, so I have switched to the PIMPL idiom in most cases where I used to have a nested class. I always put enums either in the class if it is used only by that class, or outside the class in the same namespace as the class when more than one class uses the enum.
I can see a con for nested classes, that one may better use generic programming.
If the little class is defined outside the big one, you can make the big class a class template and use any "little" class you may need in the future with the big class.
Generic programming is a powerful tool, and, IMHO, we should keep it in mind when developing extensible programs. Strange, that no one has mentioned this point.
Only problem with nested classes that I bumped into yet was that C++ does not let us refer to the object of the enclosing class, in the nested class functions. We cannot say "Enclosing::this"
(But maybe there's a way?)
Related
This question already has answers here:
What are the differences between struct and class in C++?
(30 answers)
Closed 2 months ago.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
In what scenarios is it better to use a struct vs a class in C++?
The differences between a class and a struct in C++ are:
struct members and base classes/structs are public by default.
class members and base classes/structs are private by default.
Both classes and structs can have a mixture of public, protected and private members, can use inheritance, and can have member functions.
I would recommend you:
use struct for plain-old-data structures without any class-like features;
use class when you make use of features such as private or protected members, non-default constructors and operators, etc.
As everyone else notes there are really only two actual language differences:
struct defaults to public access and class defaults to private access.
When inheriting, struct defaults to public inheritance and class defaults to private inheritance. (Ironically, as with so many things in C++, the default is backwards: public inheritance is by far the more common choice, but people rarely declare structs just to save on typing the "public" keyword.
But the real difference in practice is between a class/struct that declares a constructor/destructor and one that doesn't. There are certain guarantees to a "plain-old-data" POD type, that no longer apply once you take over the class's construction. To keep this distinction clear, many people deliberately only use structs for POD types, and, if they are going to add any methods at all, use classes. The difference between the two fragments below is otherwise meaningless:
class X
{
public:
// ...
};
struct X
{
// ...
};
(Incidentally, here's a thread with some good explanations about what "POD type" actually means: What are POD types in C++?)
There are lots of misconceptions in the existing answers.
Both class and struct declare a class.
Yes, you may have to rearrange your access modifying keywords inside the class definition, depending on which keyword you used to declare the class.
But, beyond syntax, the only reason to choose one over the other is convention/style/preference.
Some people like to stick with the struct keyword for classes without member functions, because the resulting definition "looks like" a simple structure from C.
Similarly, some people like to use the class keyword for classes with member functions and private data, because it says "class" on it and therefore looks like examples from their favourite book on object-oriented programming.
The reality is that this completely up to you and your team, and it'll make literally no difference whatsoever to your program.
The following two classes are absolutely equivalent in every way except their name:
struct Foo
{
int x;
};
class Bar
{
public:
int x;
};
You can even switch keywords when redeclaring:
class Foo;
struct Bar;
(although this breaks Visual Studio builds due to non-conformance, so that compiler will emit a warning when you do this.)
and the following expressions both evaluate to true:
std::is_class<Foo>::value
std::is_class<Bar>::value
Do note, though, that you can't switch the keywords when redefining; this is only because (per the one-definition rule) duplicate class definitions across translation units must "consist of the same sequence of tokens". This means you can't even exchange const int member; with int const member;, and has nothing to do with the semantics of class or struct.
The only time I use a struct instead of a class is when declaring a functor right before using it in a function call and want to minimize syntax for the sake of clarity. e.g.:
struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare());
From the C++ FAQ Lite:
The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.
struct and class are otherwise functionally equivalent.
OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.
You can use "struct" in C++ if you are writing a library whose internals are C++ but the API can be called by either C or C++ code. You simply make a single header that contains structs and global API functions that you expose to both C and C++ code as this:
// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif
// Put your C struct's here
struct foo
{
...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;
// Put your C API functions here
void bar(foo *fun);
#ifdef __cpp
}
#endif
Then you can write a function bar() in a C++ file using C++ code and make it callable from C and the two worlds can share data through the declared struct's. There are other caveats of course when mixing C and C++ but this is a simplified example.
One place where a struct has been helpful for me is when I have a system that's receiving fixed format messages (over say, a serial port) from another system. You can cast the stream of bytes into a struct that defines your fields, and then easily access the fields.
typedef struct
{
int messageId;
int messageCounter;
int messageData;
} tMessageType;
void processMessage(unsigned char *rawMessage)
{
tMessageType *messageFields = (tMessageType *)rawMessage;
printf("MessageId is %d\n", messageFields->messageId);
}
Obviously, this is the same thing you would do in C, but I find that the overhead of having to decode the message into a class is usually not worth it.
As every one says, the only real difference is the default access. But I particularly use struct when I don't want any sort of encapsulation with a simple data class, even if I implement some helper methods. For instance, when I need something like this:
struct myvec {
int x;
int y;
int z;
int length() {return x+y+z;}
};
To answer my own question (shamelessly), As already mentioned, access privileges are the only difference between them in C++.
I tend to use a struct for data-storage only. I'll allow it to get a few helper functions if it makes working with the data easier. However as soon as the data requires flow control (i.e. getters/setters that maintain or protect an internal state) or starts acquring any major functionality (basically more object-like), it will get 'upgraded' to a class to better communicate intent.
For C++, there really isn't much of a difference between structs and classes. The main functional difference is that members of a struct are public by default, while they are private by default in classes. Otherwise, as far as the language is concerned, they are equivalent.
That said, I tend to use structs in C++ like I do in C#, similar to what Brian has said. Structs are simple data containers, while classes are used for objects that need to act on the data in addition to just holding on to it.
Structs (PODs, more generally) are handy when you're providing a C-compatible interface with a C++ implementation, since they're portable across language borders and linker formats.
If that's not a concern to you, then I suppose the use of the "struct" instead of "class" is a good communicator of intent (as #ZeroSignal said above). Structs also have more predictable copying semantics, so they're useful for data you intend to write to external media or send across the wire.
Structs are also handy for various metaprogramming tasks, like traits templates that just expose a bunch of dependent typedefs:
template <typename T> struct type_traits {
typedef T type;
typedef T::iterator_type iterator_type;
...
};
...But that's really just taking advantage of struct's default protection level being public...
As others have pointed out
both are equivalent apart from default visibility
there may be reasons to be forced to use the one or the other for whatever reason
There's a clear recommendation about when to use which from Stroustrup/Sutter:
Use class if the class has an invariant; use struct if the data members can vary independently
However, keep in mind that it is not wise to forward declare sth. as a class (class X;) and define it as struct (struct X { ... }).
It may work on some linkers (e.g., g++) and may fail on others (e.g., MSVC), so you will find yourself in developer hell.
Both struct and class are the same under the hood though with different defaults as to visibility, struct default is public and class default is private. You can change either one to be the other with the appropriate use of private and public. They both allow inheritance, methods, constructors, destructors, and all the rest of the goodies of an object oriented language.
However one huge difference between the two is that struct as a keyword is supported in C whereas class is not. This means that one can use a struct in an include file that can be #include into either C++ or C so long as the struct is a plain C style struct and everything else in the include file is compatible with C, i.e. no C++ specific keywords such as private, public, no methods, no inheritance, etc. etc. etc.
A C style struct can be used with other interfaces which support using C style struct to carry data back and forth over the interface.
A C style struct is a kind of template (not a C++ template but rather a pattern or stencil) that describes the layout of a memory area. Over the years interfaces usable from C and with C plug-ins (here's looking at you Java and Python and Visual Basic) have been created some of which work with C style struct.
An advantage of struct over class is that it save one line of code, if adhering to "first public members, then private". In this light, I find the keyword class useless.
Here is another reason for using only struct and never class. Some code style guidelines for C++ suggest using small letters for function macros, the rationale being that when the macro is converted to an inline function, the name shouldn't need to be changed. Same here. You have your nice C-style struct and one day, you find out you need to add a constructor, or some convenience method. Do you change it to a class? Everywhere?
Distinguishing between structs and classes is just too much hassle getting into the way of doing what we should be doing - programming. Like so many of C++'s problems it arises out of the strong desire for backwards compatibility.
They are pretty much the same thing. Thanks to the magic of C++, a struct can hold functions, use inheritance, created using "new" and so on just like a class
The only functional difference is that a class begins with private access rights, while a struct begins with public. This is the maintain backwards compatibility with C.
In practice, I've always used structs as data holders and classes as objects.
Class.
Class members are private by default.
class test_one {
int main_one();
};
Is equivalent to
class test_one {
private:
int main_one();
};
So if you try
int two = one.main_one();
We will get an error: main_one is private because its not accessible. We can
solve it by initializing it by specifying its a public ie
class test_one {
public:
int main_one();
};
Struct.
A struct is a class where members are public by default.
struct test_one {
int main_one;
};
Means main_one is private ie
class test_one {
public:
int main_one;
};
I use structs for data structures where the members can take any value, it's
easier that way.
After years of programming in C++, my main language, I come to the dead conclusion that this is another one of C++ dumb feature.
There is no real difference between the two, and no reason why I should spend extra time deciding whether I should define my entity as a struct or a class.
To answer this question, feel free to always define your entity as a struct. Members will be public by default which is the norm. But even more importantly, inheritance will be public by default. Protected inheritance, and even worse, private inheritance, are the exceptions.
I have never had a case where private inheritance was the right thing to do. Yes I tried to invent problems to use private inheritance but it didn't work. And Java, the role model of Object Oriented programming defaults to public inheritance if you don't use the accessor keywords. And by the way, Java doesn't allow accessor keywords on inherited classes, they can only be publicly inherited. So you can see, the cpp team really fell down here.
Another frustrating thing about this, is that if you define as a class and declare as a struct you get compilation warning. As though this is something that impacted the performance or accuracy of your program. One answer also noted that MSVC may propogate a compiler error instead.
Those persons that use classes when it is raining and structs when it is shining are doing so based on what they have been taught. It's not something they discovered to be true. Java does not have a pair of names for classes, and only have the class keyword. If you want a data structure, simply make all your members public and don't add functions. This works in Java and I don't see any problem. What's the problem? You need 4 or 5 characters of BOM code to determine how to interpret the context of a class entity.
they're the same thing with different defaults (private by default for class, and public by default for struct), so in theory they're totally interchangeable.
so, if I just want to package some info to move around, I use a struct, even if i put a few methods there (but not many). If it's a mostly-opaque thing, where the main use would be via methods, and not directly to the data members, i use a full class.
Structs by default have public access and classes by default have private access.
Personally I use structs for Data Transfer Objects or as Value Objects. When used as such I declare all members as const to prevent modification by other code.
Just to address this from a C++20 Standardese perspective (working from N4860)...
A class is a type. The keywords "class" and "struct" (and "union") are - in the C++ grammar - class-keys, and the only functional significance of the choice of class or struct is:
The class-key determines whether ... access is public or private by default (11.9).
Data member default accessibility
That the class keyword results in private-by-default members, and `struct keyword results in public-by-default members, is documented by the examples in 11.9.1:
class X {
int a; // X::a is private by default: class used
...vs...
struct S {
int a; // S::a is public by default: struct used
Base class default accessibility
1.9 also says:
In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class.
Circumstances where consistent use of struct or class is required...
There's a requirement:
In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration (9.2.8.3).
...in any elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration (9.7.1), the union class-key shall be used to refer to a union (11.5), and either the class or struct class-key shall be
used to refer to a non-union class (11.1).
The following example (of when consistency is not required) is provided:
struct S { } s;
class S* p = &s; // OK
Still, some compilers may warn about this.
Interestingly, while the types you create with struct, class and union are all termed "classes", we have...
A standard-layout struct is a standard layout class defined with the class-key struct or the class-key class.
...so in Standardese, when there's talk of a standard-layout struct it's using "struct" to imply "not a union"s.
I'm curious if there are similar use of "struct" in other terminology, but it's too big a job to do an exhaustive search of the Standard. Comments about that welcome.
Technically both are the same in C++ - for instance it's possible for a struct to have overloaded operators etc.
However :
I use structs when I wish to pass information of multiple types simultaneously
I use classes when the I'm dealing with a "functional" object.
Hope it helps.
#include <string>
#include <map>
using namespace std;
struct student
{
int age;
string name;
map<string, int> grades
};
class ClassRoom
{
typedef map<string, student> student_map;
public :
student getStudentByName(string name) const
{ student_map::const_iterator m_it = students.find(name); return m_it->second; }
private :
student_map students;
};
For instance, I'm returning a struct student in the get...() methods over here - enjoy.
When would you choose to use struct
and when to use class in C++?
I use struct when I define functors and POD. Otherwise I use class.
// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
bool operator()(int first, int second)
{ return first < second; }
};
class mycompare : public std::binary_function<int, int, bool>
{
public:
bool operator()(int first, int second)
{ return first < second; }
};
I use structs when I need to create POD type or functor.
All class members are private by default and all struct members are public by default.
Class has default private bases and Struct has default public bases. Struct in case of C cannot have member functions where as in case of C++ we can have member functions being added to the struct. Other than these differences, I don't find anything surprising about them.
I use struct only when I need to hold some data without any member functions associated to it (to operate on the member data) and to access the data variables directly.
Eg: Reading/Writing data from files and socket streams etc. Passing function arguments in a structure where the function arguments are too many and function syntax looks too lengthy.
Technically there is no big difference between class and struture except default accessibility.
More over it depends on programming style how you use it.
Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
I thought that Structs was intended as a Data Structure (like a multi-data type array of information) and classes was inteded for Code Packaging (like collections of subroutines & functions)..
:(
I never use "struct" in C++.
I can't ever imagine a scenario where you would use a struct when you want private members, unless you're willfully trying to be confusing.
It seems that using structs is more of a syntactic indication of how the data will be used, but I'd rather just make a class and try to make that explicit in the name of the class, or through comments.
E.g.
class PublicInputData {
//data members
};
Out of idle curiosity, I've typed in the following piece of code:
pure struct Foo{ }
pure class Bar{ }
This, apparently, compiles with both DMD and LDC. I have no idea what it does (if it does), as calling impure functions from such structs/classes is OK. So, what does attaching pure to a class or a struct change?
In general, D has a tendency to ignore attributes when they don't apply, if nothing else, because generic code is easier to write that way (at times, it avoids having to write a bunch of static ifs just to avoid applying attributes to code where they wouldn't have any effect) - one example being that you can put static on a pretty much any declaration at module level, but it doesn't actually do anything for most of them, and the compiler doesn't complain about it.
However, for whatever reason, the way that attributes get applied when you mark a struct or class with them is a bit inconsistent. For instance, if you marked a struct or class with #safe, then every function in that struct or class will be #safe unless it's marked with #trusted or #system. In contrast, if you mark the class or struct with pure, it does absolutely nothing - just like with static. It's simply ignored.
My best guess as to why something like #safe is applied to all of the functions inside the struct or class, whereas an attribute like pure or nothrow is ignored is that #safe, #trusted, and #system can be undone on specific functions within the struct or class by using a different attribute explicitly on that function, whereas for most attributes, there is no way to reverse them.
Unfortunately however, the fact that you can mark a class or struct with attributes when they either don't apply or when they apply just to the declarations within the class or struct and not the class or struct itself does tend to confuse people (e.g. some people think that immutable class C {..} means something special for the class, when all it means is that the declarations within the class are immutable; it would be no different from doing class C { immutable { ... } }). So, ultimately, you have to be familiar with what each attribute actually does to know when they actually apply to the class or struct, when they really just apply to the declarations inside the class or struct, and when they're simply ignored.
Personally, I never apply attributes to a class or struct unless they're specifically meant to apply to the struct or class and not on the functions within it (e.g. final on a class means something separate from putting it on the functions within that class), and the number of attributes that actually apply to a struct or class is pretty small. static does in some contexts (just not at module level), abstract and final do for classes, and the access modifiers (public, private, etc.) do. Per TDPL, synchronized is also supposed to be special for the class, but synchronized classes have never really been implemented (just synchronized functions). So, I might have missed one, but off the top of my head, that's the full list of attributes that can actually apply to a struct or class, and all of the others are either ignored or apply to the declarations within the struct or class but not to the struct or class itself.
It changes nothing. The D compiler simply ignores many keywords when they're placed in locations they wouldn't make sense.
A quick test to prove this:
pure struct S {
static void bar() {}
}
pure unittest {
static assert(!__traits(compiles, S.bar()));
}
Is it me or the implementation of object oriented paradigm in C++ is missing the concept of class namespace?
Here is an example of what I mean:
Document { Header {} Body {} Footer {} }
Document is an object that can have a header, body, and footer.
A straight forward way to address such object and its elements from external namespace is
Document
Document::Header
Document::Body
Document::Footer
Is there a way to achieve such naming structure in C++ without imposing a restriction on the definition of Document class?
1) namespace Document { ... }
This case requires an object class inside its own namespace and using Document::Document seems redundant and unintended.
2) namespace Document { class ... } typedef Document::Document document;
This case gives document and Document::{part}, which in case sensitive language may seem weird and unrelated.
3) class Document { class ... };
This case requires including Document header in definition of every nested class and doesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.
4) class document { class ... }; class Document : public document {}
This case is close to what is intended but costs an extra class and inheritance.
!) Ideally, what I'd like to have is
namespace class Document {
class Header;
class Body;
class Footer;
class Document; // linked with the parent namespace as with its own name space
}
Document doc; // ok, resolves Document as a class
Document::{Part} docPart; // ok, resolves Document as namespace
.) Is there any other reasonable way to achieve what is intended without unreasonable extra cost?
I'm also not exactly sure why such trivial things are not a standard way to do it. :/ Any specific reason?
--- clarification ---
To address some of the raised questions,
"What is it useful for?" 1) Plain language 2) Transparent mapping from a language construct to an object's abstract model and vice versa.
"Why would one want to derive an object from its parts?" Not every entity introduced by an object has to be its part. It can be its essence, for example. E.g.:
Document { Skeleton{} Parts { Header {} Body {} Footer {} } }
--- abstract framework ---
Think of an object as a module whose definition may use external symbols and introduce some of its own along with the definition of its own logical entity, to which they should remain related since it introduces them.
--- point ---
The whole module is a definition of an object. It would be nice to be able to use it as such without any additional linguistic ridicules.
=== resolution ===
Thank you for your feedback.
Until there is a way in C++ to link a namespace name to a class, I guess I'll use the
ObjectName { ... Object {} } -> ObjectName::Object, ObjectName::Part
construct in such cases. It may be not as short as I'd like to, but at least transparent enough, with no extra cost, and can be used with forward declarations.
Your third option - using nested class declarations / definitions, will get you the ideal scope resolution as you want (though it will not involve a single namespace).
class Document
{
public:
class Header
{
// Header class declaration here
};
class Body
{
// Body class declaration here
};
class Footer
{
// Footer class declaration here
};
// Document declaration here.
};
Your concerns with that option are:
Requires including Document header in definition of every nested class
Yes - the nested classes are inextricably linked to the surrounding class, their implementations will depend on the definition of the surrounding class because it contains the definitions of the nested classes. This is unavoidable.
Dpesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.
What you are trying to do seems to make very little logical sense - you are trying to define something based on its own parts, which is a circular definition. What are you trying to achieve by deriving Document from Header, Body or Footer?
The final line of your question suggests that you find your desired functionality "trivial", but in my opinion and experience it is far from trivial. You seem to be conflating a namespace and a class because of syntactical similarities, but they are entirely different concepts. You have to separate the two in your mind, they have very little overlap besides some scoping effects and scope resolution syntax. Your "Document" must be either a namespace and a class. Pick one ;) (technically it's actually possible to have both a namespace Document and a class Document, but this is likely to be a source of confusion.
)
Your first case does exactly what you say you want. There's nothing redundant about Document::Document -- it refers to the Document class in the Document namespace. There might very well be a Document class in the XML namespace, and another one in the MyCompany namespace.
Your second case looks like an attempt to essentially defeat the purpose of using namespaces. If you don't want to use a namespace, don't -- just use the global (unspecified) namespace and risk collisions. If you only want to avoid the Document:: part in the code that's related to your Document class, add a using namespace Document directive in that code.
You just enclose the part classes within the Document class.
class Document {
public:
class Header;
class Body;
class Footer;
};
You can validly use this:
Document myDoc; // Type Document
Document::Header myHeader;
3) class Document { class ... };
This case requires including Document header in definition of every nested class and doesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.
No, this design is what makes the most sense. I don't understand what you think the difference would be between class and namespace class.
class Document
{
public:
class Header
{
};
Header m_header;
class Body
{
};
Body m_Body;
};
What's wrong with this design? You access the types via Document::Header. You access via instances like myDocument.m_header.
The only inherent oddness is that you can't name a type and member variable the same, but there are plenty of ways around that and it's a superficial restriction really.
Just because a Document object contains a Header object doesn’t mean that the Header class should be contained in the Document class. At least, that’s not usually done.
I would nest classes only in rare instances; namely, when the nested class is an implementation detail of the outer class, and isn’t exposed to the outside world (but even then it’s common to forego nesting).
This, by the way, is independent of C++: classes in general are rarely nested except to hide implementation details. Frameworks to model object relations as in your case wouldn’t normally use nesting. Instead, you might have something like this:
namespace Html {
class Document;
class Header;
class Body;
// …
}
C++ in particular uses flat namespace hierarchies but the above would equally apply to C# or Java.
Finally, to explicitly address your introductory question:
Is it me or the implementation of object oriented paradigm in C++ is missing the concept of class namespace?
C+ has this concept to the same extent as other modern OO languages: a class forms a namespace for the purpose of name lookup so you can achieve what you want. But for the reason mentioned above I don’t think it’s a particularly desirable goal.
It's not totally clear to me how much you want to expose the nested
classes, but if they are part of Document, they probably should be
nested classes. Your example of what you mean, at the start of your
code, is exactly how one would do this in C++:
class Document
{
public: // or not?
class Header
{
};
class Body
{
};
class Footer
{
};
};
About the only objection I can see is that implementation files only
concerned with Document::Header must include the entire Document
class definition, but I don't think this is a major problem; if
Document::Header really isn't independent, then it seems reasonable to
require this. With regards to your second objection to this solution:
you never want to make an object derive from its parts: a Document
hasA Header; it isn't an isA relationship.
If it does make sense for Header et al to be used separately, then the
best solution is to define them outside of the Document class, either
giving them more descriptive names (e.g. DocumentHeader) or wrapping
them in a special namespace (e.g. namespace DocumentParts). Depending
on their relationship with Document, it might make sense to use
typedef in Document so that they can be referred to as either
DocumentParts::Header or Document::Header.
I'm creating a class called ImageLoader that will be used to load various image formats. For various image formats there are certain structs used. For example with bmp files you have a BITMAPFILEHEADER struct and two others.
What I want to know is, when I'm putting my class definition in the header file, do I make the struct typedefs part of the class definition, or should they be separate, outside the class definition?
I'm not sure because if I was just declaring a struct variable, that would obviously happen in the class, but because I'm defining a type, I'm not sure if it's considered good design to define a type inside a class.
My general rule is that if it will only be used in conjunction with that class, then declare it inside (it implies ownership); otherwise declare it separately.
You get better encapsulation if you leave out everything from the header that you possibly can. Even if some methods of your class need parameters or return types of the struct, you might get away with a forward declaration.
The only time you need to put it in the header is when it's part of the public interface.
As to whether it goes in the class or not, consider whether it's useful on its own or if it is totally subservient to the class. If it can stand alone it should probably go in its own header.
I would not say that declaring a type in a class is an indicator of bad design. Assuming that your mention of "design" means something along the lines of "readability", I would be a stickler for consistency and insist that the same relationships be expressed in the same way.
Otherwise, you are not going to be struck down by a divine wrath for nesting types (Considering SGI is not a smoldering crater). This is pretty context-centric, so there are no hard and fast rules outside of what you define based on your requirements.
If client accessibility is not an issue, I declare most everything in an appropriate scope in headers and just document what my code means. Again, this is if I do not have strict usage/readability guidelines to enforce. I'd go with Mark's suggestion if I did.
Two cents: You could try enumerating image types and using one public struct for config data so that you could justify pulling everything else behind closed doors.
BITMAPFILEHEADER is a structure defined in the Win32 Platform SDK. I'm not sure I've understood your request about it and your class...
In general, if you are defining structures that are not exposed to the client of your class, I'd define them in the private part of your class, or in a sub-namespace Details in your header file, e.g.:
namespace YourCoolLibrary
{
namespace Details
{
struct SomeInternalStructure
{
...
};
} // namespace Details
class YourCoolClass
{
...
private:
Details::SomeInternalStructure m_something;
};
} // namespace YourCoolLibrary
There are even many more choices. If you put it in the class you have to choose if it's public, protected, or private making the class definition visible for every user of the class, only derived classes or no other classes.
If you do not need the details of the class definition I'd put only forward declarations into ImageLoader to keep it simpler. The full definition of the inner class then goes into the implementation file.
My rule of thumb is to make names as local as possible, so if I use it accidentally at the wrong place the compiler will complain.
If the typedef logically belongs into the class you are creating, put it inside; if it would make sense on a global level, leave it outside.
I've recently seen several people doing things like this here on Stackoverflow:
class A:
foo = 1
class B:
def blah(self):
pass
In other words, they have nested classes. This works (although people new to Python seem to run into problems because it doesn't behave like they thought it would), but I can't think of any reason to do this in any language at all, and certainly not in Python. Is there such a usecase? Why are people doing this? Searching for this it seems it's reasonably common in C++, is there a good reason there?
The main reason for putting one class in another is to avoid polluting the global namespace with things that are used only inside one class and therefore doesn't belong in the global namespace. This is applicable even to Python, with the global namespace being a namespace of a particular module. For example if you have SomeClass and OtherClass, and both of them need to read something in a specialized way, it is better to have SomeClass.Reader and OtherClass.Reader rather than SomeClassReader and OtherClassReader.
I have never encountered this in C++, though. It can be problematic to control access to the outer class' fields from a nested class. And it is also pretty common to have just one public class in a compilation unit defined in the header file and some utility classes defined in the CPP file (the Qt library is a great example of this). This way they aren't visible to "outsiders" which is good, so it doesn't make much sense to include them in the header. It also helps to increase binary compatibility which is otherwise a pain to maintain. Well, it's a pain anyway, but much less so.
A great example of a language where nested classes are really useful is Java. Nested classes there automatically have a pointer to the instance of the outer class that creates them (unless you declare the inner class as static). This way you don't need to pass "outer" to their constructors and you can address the outer class' fields just by their names.
It allows you to control the access of the nested class- for example, it's often used for implementation detail classes. In C++ it also has advantages in terms of when various things are parsed and what you can access without having to declare first.
I am not a big fan of python, but to me this type of decisions are more semantical than syntactical. If you are implementing a list, the class Node inside List is not a class in itself meant to be used from anywhere, but an implementation detail of the list. At the same time you can have a Node internal class inside Tree, or Graph. Whether the compiler/interpreter allows you to access the class or not is in a different thing. Programing is about writing specifications that the computer can follow and other programers can read, List.Node is more explicit in that Node is internal to List than having ListNode as a first level class.
In some languages, the nested class will have access to variables that are in scope within the outer class. (Similarly with functions, or with class-in-function nesting. Of course, function-in-class nesting just creates a method, which behaves fairly unsurprisingly. ;) )
In more technical terms, we create a closure.
Python lets you do a lot of things with functions (including lambdas) that in C++03 or Java you need a class for (although Java has anonymous inner classes, so a nested class doesn't always look like your example). Listeners, visitors, that kind of thing. A list comprehension is loosely a kind of visitor:
Python:
(foo(x) if x.f == target else bar(x) for x in bazes)
C++:
struct FooBar {
Sommat operator()(const Baz &x) const {
return (x.f == val) ? foo(x) : bar(x);
}
FooBar(int val) : val(val) {}
int val;
};
vector<Sommat> v(bazes.size());
std::transform(bazes.begin(), bazes.end(), v.begin(), FooBar(target));
The question that C++ and Java programmers then ask themselves is, "this little class that I'm writing: should it appear in the same scope as the big class that needs to use it, or should I confine it within the scope of the only class that uses it?"[*]
Since you don't want to publish the thing, or allow anyone else to rely on it, often the answer in these cases is a nested class. In Java, private classes can serve, and in C++ you can restrict classes to a TU, in which case you may no longer care too much what namespace scope the name appears in, so nested classes aren't actually required. It's just a style thing, plus Java provides some syntactic sugar.
As someone else said, another case is iterators in C++. Python can support iteration without an iterator class, but if you're writing a data structure in C++ or Java then you have to put the blighters somewhere. To follow the standard library container interface you'll have a nested typedef for it whether the class is nested or not, so it's fairly natural to think, "nested class".
[*] They also ask themselves, "should I just write a for loop?", but let's suppose a case where the answer to that is no...
In C++ at least, one major common use-case for nested classes is iterators in containers. For example, a hypothetical implementation might look something like this:
class list
{
public:
class iterator
{
// implementation code
};
class const_iterator
{
// implementation code
};
};
Another reason for nested classes in C++ would be private implementation details like node classes for maps, linked lists, etc.
"Nested classes" can mean two different things, which can be split into three different categories by intent. The first one is purely stylistic, the other two are used for practical purposes, and are highly dependent on the features language where they are used.
Nested class definitions for the sake of creating a new namespace and/or organizing your code better. For example, in Java this is accomplished through the use static nested classes, and it is suggested by the official documentation as a way to create more readable and maintainable code, and to logically group classes together. The Zen of Python, however, suggests that you nest code blocks less, thus discouraging this practice.
import this
In Python you'd much more often see the classes grouped in modules.
Putting a class inside another class as part of its interface (or the interface of the instances). First, this interface can be used by the implementation to aid subclassing, for example imagine a nested class HTML.Node which you can override in a subclass of HTML to alter the class used to create new node instances. Second, this interface might be used by the class/instance users, though this is not that useful unless you are in the third case described below.
In Python at least, you don't need to nest the definitions to achieve either of those, however, and it's probably very rare. Instead, you might see Node defined outside of the class and then node_factory = Node in the class definition (or a method dedicated to creating the nodes).
Nesting the namespace of the objects, or creating different contexts for different groups of objects. In Java, non-static nested classes (called inner classes) are bound to an instance of the outer class. This is very useful because it lets you have instances of the inner class that live inside different outer namespaces.
For Python, consider the decimal module. You can create different contexts, and have things like different precisions defined for each context. Each Decimal object can assigned a context on creation. This achieves the same as an inner class would, through a different mechanism. If Python supported inner classes, and Context and Decimal were nested, you'd have context.Decimal('3') instead of Decimal('3', context=context).
You could easily create a metaclass in Python that lets you create nested classes that live inside of an instance, you can even make it produce proper bound and unbound class proxies that support isinstance correctly through the use of __subclasscheck__ and __instancecheck__. However, it won't gain you anything over the other simpler ways to achieve the same (like an additional argument to __init__). It would only limit what you can do with it, and I have found inner classes in Java very confusing every time I had to use them.
In Python, a more useful pattern is declaration of a class inside a function or method. Declaration of a class in the body of another class, as people have noted in other answers, is of little use - yes, it does avoid pollution of the module namespace, but since there_is_ a module namespace at all, a few more names on it do not bother. Even if the extra classes are not intended to be instantiated directly by users of the module, putting then on the module root make their documentation more easily accessible to others.
However, a class inside a function is a completely different creature: It is "declared" and created each time the code containing the class body is run. This gives one the possibility of creating dynamic classes for various uses - in a very simple way. For example, each class created this way is in a different closure, and can have access to different instances of the variables on the containing function.
def call_count(func):
class Counter(object):
def __init__(self):
self.counter = 0
def __repr__(self):
return str(func)
def __call__(self, *args, **kw):
self.counter += 1
return func(*args, **kw)
return Counter()
And using it on the console:
>>> #call_count
... def noop(): pass
...
>>> noop()
>>> noop()
>>> noop.counter
2
>>> noop
<function noop at 0x7fc251b0b578>
So, a simple call_counter decorator could use a static "Counter" class, defined outside the function, and receiving func as a parameter to its constructor - but if you want to tweak other behaviors, like in this example, making repr(func) return the function representation, not the class representation, it is easier to be made this way.
.