I can understand the use for one level of namespaces. But 3 levels of namespaces. Looks insane. Is there any practical use for that? Or is it just a misconception?
Hierarchical namespaces do have a use in that they allow progressively more refined definitions. Certainly a single provider may produce two classes with the same name. Often the first level is occupied by the company name, the second specifies the product, the third (and possibly more) my provide the domain.
There are also other uses of namespace segregation. One popular situation is placing the base classes for a factory pattern in its own namespace and then derived factories in their own namespaces by provider. E.g. System.Data, System.Data.SqlClient and System.Data.OleDbClient.
Obviously it's a matter of opinion. But it really boils down to organization. For example, I have a project which has a plugin api that has functions/objects which look something like this:
plugins::v1::function
When 2.0 is rolled out they will be put into the v2 sub-namespace. I plan to only deprecate but never remove v1 members which should nicely support backwards compatibility in the future. This is just one example of "sane" usage. I imagine some people will differ, but like I said, it's a matter of opinion.
Big codebases will need it. Look at boost for an example. I don't think anyone would call the boost code 'insane'.
If you consider the fact that at any one level of a hierarchy, people can only comprehend somewhere very roughly on the order of 10 items, then two levels only gives you 100 maximum. A sufficiently big project is going to need more, so can easily end up 3 levels deep.
I work on XXX application in my company yyy, and I am writing a GUI subsystem. So I use yyy::xxx::gui as my namespace.
You can easily find yourself in a situation when you need more than one level. For example, your company has a giant namespace for all of its code to separate it from third party code, and you are writing a library which you want to put in its own namespace. Generally, whenever you have a very large and complex system, which is broken down hierarchically, it is reasonable to use several namespace levels.
It depends on your needs and programming style. But one of the benefits of namespace is to help partition name space (hence the name). With a single namespace, as your project is increases in size and complexity, so does the likelihood of name-collision.
If you're writing code that's meant to be shared or reused, this becomes even more important.
I agree for applications. Most people that use multiple levels of namespaces (in my experience) come from a Java or .NET background where the noise is significantly less. I find that good class prefixes can take the place of multiple levels of namespaces.
But I have seen good use of multiple namespace levels in boost (and other libraries). Everything is in the boost namespace, but libraries are allowed (encouraged?) to be in their own namespace. For example - boost::this_thread namespace. It allows things like...
boost::this_thread::get_id()
boost::this_thread::interruption_requested()
"this_thread" is just a namespace for a collection of free functions. You could do the same thing with a class and static functions (i.e. the Java way of defining a free function), but why do something unnatural when the language has a natural way of doing it?
Just look at the .Net base class library to see a namespace hierarchy put to good use. It goes four or five levels deep in a few places, but mostly it's just two or three, and the organization is very nice for finding things.
The bigger the codebase the bigger the need for hierarchical namespaces. As your project gets bigger and bigger you find you need to break it out in ways to make it easier to find stuff.
For instance we currently use a 2 level hierarchy. However some of the bigger portions we are now talking about breaking them out into 3 levels.
Related
This is confusing me a great deal. All code examples being namespaceA and namespaceB and the method names being foo() and bar() are not helping, either. The way everyone explains it makes it seem as though namespaces are a relic of pre-OOP times where you could not say 'class car give fuel level' but had to go to this from another approach. But when I now want to do a C++ level, what is the point of using namespaces? Not that headers are confusing enough already, namespaces make absolutely no sense to me, in either how they work or why to use them.
Let's say I have a project built around Traffic, for example. You'd have classes for the Cars and its components, the Drivers and Passengers and the Road.
Now, the Road has Cars and each Car has Persons. What would this look like?
Would you have the namespaces Road, Car, Person? Would the main() use the namespace Road to access the stuff in the header? Would the namespace Road include the namespace Car, and the Car include the namespace Person, and would through this the main() have access to the methods in Person? This is the way most guides explain this, but I don't really see the advantage of this over just importing the header file, wouldn't that have the same effect?
Or would you put multiple headers in the same namespace, such as namespace Traffic with all those classes? Can you nest namespaces?
I know C# and never knew it had namespaces until I looked it up just now, and never needed it, and in Java, Python, and Dart, those also never came up. Since I am trying to teach myself C++, I am kind of stranded here now, asking this question here. So far, I also never used them in C++, but I want to learn it properly.
For small, self-contained projects, there's not much need for namespaces, and you'd never create a namespace for each object or concept in your code.
Larger projects using libraries benefit from being isolated from names introduced by those libraries, as well as some internal organisation to make readability easier.
Similarly, when creating a library, it's a good idea to put its contents into a namespace so as not to cause headaches and conflicts for your users (as you don't know how large their projects will be, and what names they may want to use themselves).
To use an analogy: if you have three books, you don't bother organising them alphabetically. But, once you have a hundred, you might decide to categorise them on your bookshelf for easier reference and mental health.
And, if you now borrow another twenty books from a friend, you'd probably keep those in a separate pile so they're easier to find when you need to give them back.
So, to some degree, this is a case of… you'll know why you need it, when you need it.
If I make a library with a function calculateStuff() in it and you also make a library with a calculateStuff() function, then some other person who wants to use both our libraries at the same time is going to have a bad day. But, if we both used namespaces there's no problem since he/she can then distinguish the functions as myNamespace::calculateStuff() and yourNamespace::calculateStuff() and there's no ambiguity.
For example: std::shared_ptr vs boost::shared_ptr. Without namespaces you wouldn't be able to use both in the same program as the name shared_ptr would be ambiguous.
"[Named] Namespaces" are, as the name perhaps suggests, a way to subdivide the identifier space. In addition to solving literal conflicts ("you have more than one foo ..."), it also makes it considerably easier to find foo in a big, mature program that might well consist of hundreds or even thousands of modules.
The "name" of a variable or routine might(?) suggest what it is, but might not give any clue as to where it is, nor the context (not a technical term) of what it relates to: "it's just one name among many thousands." But, if you now group these into intelligently-chosen namespaces, you're adding a level of helpful organization to them. In a typical "great big program," especially one that is (as is also typical ...) "not entirely familiar to you," this extra level of bread-crumbs is a big bonus.
Simply put, namespaces allow to use the same names for different contexts.
Let's say you want to create two functions that take the same parameters and output text in two different ways, for the sake of simplicity you'd want to call them both print().
Since they both take the same parameters, there is no chance for function overloading here, but if you put each function in a separate namespace and then you call print(), you can simply change what the function will be doing by calling a different namespace each time.
I have a significant amount of legacy code to deal with (Fortran F90). One of the most difficult things to deal with is that each file contains a small number of massive functions, and each function has a long list of
use <module name>
The code then uses variables and data structures defined in these modules. The issue is its incredibly difficult to determine where these variables are initially defined/initialized because they're defined in one of the use modules and initialized somewhere else in the code (which is about 100 000 LOC).
Is there any way to provide namespace resolution in Fotran? From reading around, I'd guess not, so more generally, is there a good Fortran-Y way to get around this kind of an issue?
You can pick and choose what is imported from a use statement, like this:
use foo, only : bar, baz
In this case, only the bar and baz variables would be imported. This also provides a way to self-document your code, which seems like what you are looking for.
To extend, slightly, what #SethMMorton has already told you, you can also rename imported items
use foo, only : local_name=>bar, baz=>foo_baz
Unfortunately Fortran doesn't provide much in the way of language-directed discipline for doing what other languages do with namespaces. The renaming of variables by prefixing the name of the module in which they are declared would be entirely a programmer's decision and responsibility.
One can, of course, use standards- or management-enforced discipline but compilers are rarely able to help much with either of those.
Or one can console oneself with the thought that exporting many names from modules is probably a breach of good software engineering practices (encapsulation, information-hiding, what-have-you) and that the problems you are dealing with are those made by an earlier, less-disciplined generation of developers.
I have run into some quirks about my code style that I'm hoping to fix, namely with namespace usage. Let me begin by saying that I am currently employed as the sole software engineer on my particular project and don't have access to more senior level engineers to mentor and assist me. I find this particularly worrisome since I'm concerned that I'm developing really hacky practices that will get me laughed out of the room when I attempt to change jobs in the near future.
Recently I have been following and conforming to the Google style guide. I was a bit shocked when I learned that the process I had of always doing "using namespace std;" is frowned upon. In generally, most of my projects have been relatively small with little chance for reuse of my classes. However, now that I've done more research and studying, I realize why my practice is frowned upon and I'm looking to improve the way I use namespaces and the scope operator. As a result, I have the following questions:
When is it best to define a new namespace? I know that this is a weird question, and I understand that functions or variables that don't belong to a class can be group together in a namespace. However, say I have a program composed of solely classes. Is it bad practice to not define a namespace? Or should a new namespace be created solely for the project in case someone wants to interface with it later?
I know this has been argued ad nauseum, but when is good to use "std::"? I ask because I recently read up on how its better to use the "wrapped" versions of the C standard libraries (e.g., cstdlib vs. stdlib.h). I changed some of my source code over to experiment. I immediately found it weird that G++ didn't yell at me for not using std::printf() instead of just printf(). The question I have now is where do I stop in terms of the explicit scope placement? For example, the compiler doesn't yell at me about size_t or uint8_t, do I have to place "std::" in front of those as well? What is considered best practice?
Is it considering "ok" to call "using" on only the functions that you are using? Namely, I'm speaking to a case where I have a class and would do something like "using std::endl;" in the .cpp file that implements a particular class.
Edited to add a fourth question:
4. When writing code for a derived class, does it make sense to do "Baseclass::function()" whenever calling functions from the base class, even when the functions from the base class are not virtual and cannot be overloaded? Does this hinder or improve readability?
Thanks for all the help. I find this site to be a great resource!
These are practices that have served me well over many years. Hope you find this helpful.
1) Namespaces are an organizational technique for keeping like things together, usually for discoverability and to avoid name collisions with other code. They can be a great aid help when you're using intellisense-capable IDEs, making it easy to code without having to bounce back to docs to find something. Excessively fine-grained namespaces can be as detrimental to your code as no namespaces. While there's no hard rule here, but if you're consistently creating new namespaces for groups of less than 3-4 items, you are probably overdoing it. You also wouldn't typically define new namespaces inside a .cpp file, since that's the only file that would see it. I rarely see examples of the other extreme.
When working with templates, where everything is in headers, I like to create a "details" namespace under the main namespace to isolate the 'private' classes of the template library from the things that people are actually expected to use. There are other ways of achieving similar results that provide better encapsulation, but they are also more work to maintain.
2) Using statements should typically be isolated in C++ files, and not placed in headers, otherwise you lose track of what is 'used' pretty quickly in large projects. Similarly, it's best for portability and maintainability if your headers don't implicitly rely on using statements. You can make this easy to avoid by placing your using statements immediately after your include statements.
// main.cpp
#include "myheader1.h" // can't see using namespace std, ok.
using namespace std;
// Does this have std:: in front of everything that needs it?
// Maybe. Compiler won't tell me...
#include "myheader2.h"
Never put a using statement inside of an open namespace. That is, unless you really, really want to make peoples heads spin. This likely won't work like you (or the next guy) expects.
namespace A { ... }
namespace B {
using namespace A; // Don't do it!
}
In some cases, for absolutely ubiquitous namespaces, I see people put using statements in precompiled headers (is that just a VC++ thing?). I find that tolerable because they're usually local to a smaller body of code, though even there I think it's a stretch. It can facilitate the header dependency problem mentioned above.
3) That practice can get to be a nuisance, because you'll find that you have to keep going back for 'one more thing' and it can be confusing ("Wait, for this file did I use math::vector, physics::vector or std::vector?"). If you can't use the entire namespace because of collision issues, it may just be better to be explicit about at least one of the namespaces. If there's a lot of overlap, and maybe be explicit about both.
In some rare cases, with deeply nested namespaces, it may be useful to write something like this:
using namespace this::thing::is::ridiculous::someone::should::trim::it = ludicrous;
That allows to reference the namespace with a short moniker, e.g.
auto p = new ludicrous::SomeClass();
If you are going to do that, you should establish consistent conventions throughout the codebase for the namespaces that you do that to. If you use 3 different names in 3 different places, you just make the code less readable.
Anything that is designed to be at all reusable should use a namespace. Anything that has a name that has any possibility of name clashing should use a namespace, and this means pretty much anything. With smaller projects, it matters less, but in general, everything should probably go into a namespace of some kind.
Based on the C++ standard, anything that comes from a C++ standard header will be in namespace std. They may also be yanked into the global namespace. Hence, you should prefer to use std::printf or std::uint8_t and the like for maximum portability.
It's a matter of preference. For basic things that are in the std:: namespace, I'd rather be explicit personally, since it's so few characters to type. For highly nested namespace names (like some parts of boost where there are 3+ namespaces to go through), then using makes more sense.
My preference is to use std::cout for example, in other words ::FunctionName().
1. In my opinion this makes the usage obvious/explicit to reviewers/readers of the code.
2. The "using namespace " ends up including all classes of that namespace and consequently may result in clashed with your class/function names.
3. If one knows that whatever one is developing is a library creating it in its own namespace is a must.
4. For classes that are not going to be developed/interfaced to third parties, I wouldn't bother with namespaces.
Let me know if this answers your question. Otherwise come back for more detail.
Should all C++ code in a project be encapsulated into a single class with main simply calling that class? Or should the main function declare variables and classes.
If you are going to build a large project in C++, you should at the very least read Large Scale C++ Software Design by John Lakos about it. It's a little old but it sounds like you could benefit from the fundamentals in it.
Keep in mind that building a large scale system in any language is a challenge and requires skill and discipline to prevent it falling to pieces very quickly. Don't take it lightly.
That said, if your definition of "large" is different than mine then I may have alternative advice to give you. I'm assuming you're talking about a project where the word "million" will be mentioned in sentences that also contain the words "lines of code".
for large C++ projects, you should create many classes!
main should just kick things off (maybe doing a few housekeeping things) and then calling into a class that will fire up the rest of the system
If it's a class that really makes sense, sure -- but at least IME, that's a fairly rare exception, not the general rule.
Here, I'm presuming that you don't really mean all the code is in one class, but that there's a single top-level class, so essentially all main does is instantiate and use it. That class, in turn, will presumably instantiate and use other subordinate classes.
If you really mean "should all the code being contained in a single class?", then the answer is almost certainly a resounding "no", except for truly minuscule projects. Much of the design of classes in C++ (and most other OO languages) is completely pointless if all the code is in one class.
If you can put your entire project in one class without going insane, your definition of "large" may be different than most people's here. Which is fine -- just keep in mind when you ask people about a "large" c++ project, they will assume you're talking about something that takes multiple person-years to create.
That said, the same principles of encapsulation apply no matter what the size of the project. Break your logic and data into units that make sense and are not too tied together and then organize your class(es) around those divisions. Don't be afraid to try one organization and then refactor it into another organization if you find yourself copy-pasting code, or if you find one class depending too heavily on another. (Or if you find yourself with too many classes and you're creating many objects to accomplish one task where a single object would be cleaner and easier on you.)
Have fun and don't be afraid to experiment a little.
In C++ you should avoid putting entire project in one class, irrespective of big or small. At the max you can try putting it in 1 or 2 namespace (which can be split across the files).
The advantage of having multiple classes are,
Better maintainability of your code
Putting classes in multiple .h and .cpp files (i.e. small modules) help you fast debugging
If all code is in one class and changes are made somewhere then one has to compile whole project. Instead, if project is across modules, one can just compile the module where changes are made. It saves time a lot.
No! Each header/implementation file pair should represent a single class. Placing a large project in one file is a surefire way to disaster: the project become unmaintainable and compiling will take ages. Break up your code in to appropriately sized pieces.
The main function should not declare the classes, rather, the file it contains (often named something like main.cpp, driver.cpp, projectname.cpp) should use #include directives to make the compiler read the declarations in header files. Read up on C++'s separate compilation model for more info.
Some newcomers to C++ find the compilation model - as well as error codes generated when you screw it up - incomprehensible or intimidating and give up thinking it's not worth it. Don't let this be you. Learn how to properly organize your code.
I have been working on this plugin system. I thought I passed design and started implementing. Now I wonder if I should revisit my design. my problem is the following:
Currently in my design I have:
An interface class FileNameLoader for loading the names of all the shared libraries my application needs to load. i.e. Load all files in a directory, Load all files specified in a XML file, Load all files user inputs, etc.
An Interface class LibLoader that actually loads the shared object. This class is only responsible for loading a shared object once its file name has been given. There are various ways one may need to load a shared lib. i.e. Use RTLD_NOW/RTLD_LAZY...., check if lib has been already loaded, etc.
An ABC Plugin which loads the functions I need from a handle to a library once that handle is supplied. There are so many ways this could change.
An interface class PluginFactory which creates Plugins.
An ABC PluginLoader which is the mother class which manages everything.
Now, my problem is I feel that FileNameLoader and LibLoader can go inside Plugin. But this would mean that if someone wanted to just change RTLD_NOW to RTLD_LAZY he would have to change Plugin class. On the other hand, I feel that there are too many classes here. Please give some input. I can post the interface code if necessary. Thanks in advance.
EDIT:
After giving this some thought, I have come to the conclusion that more interfaces is better (In my scenario at least). Suppose there are x implementations of FileNameLoader, y implementations of LibLoader, z implementations of Plugin. If I keep these classes separate, I have to write x + y + z implementation classes. Then I can combine them to get any functionality possible. On the other hand, if all these interfces were in Plugin class, I'd have to write x*y*z implementation classes to get all the possible functionalities which is larger than x + y + z given that there are at least 2 implementations for an interface. This is just one side of it. The other advantage is, the purpose of the interfaces are more clearer when there are more interfaces. At least that is what I think.
My c++ projects generally consists of objects that implement one or more interfaces.
I have found that this approach has the following effects:
Use of interfaces enforces your design.
(my opinion only) ensures a better program design.
Related functionality is grouped into interfaces.
The compiler will let you know if your implementation of the interface is incomplete or incorrect (good for changes to interfaces).
You can pass interface pointers around instead of entire objects.
Passing around interface pointers has the benefit that you're exposing only the functionality required to other objects.
COM employs the use of interfaces heavily, as its modular design is useful for IPC (inter process communication), promotes code reuse and enable backwards compatiblity.
Microsoft use COM extensively and base their OS and most important APIs (DirectX, DirectShow, etc.) on COM, for these reasons, and although it's hardly the most accessible technology, COM's not going away any time soon.
Will these aid your own program(s)? Up to you. If you're going to turn a lot of your code into COM objects, it's definitely the right approach.
The other good stuff you get with interfaces that I've mentioned - make your own judgement as to how useful they'll be to you. Personally, I find interfaces indispensable.
Generally the only time I provide more than one interface, it will be because I have two completely different kinds of clients (eg: clients and The Server). In that case, yes it is perfectly OK.
However, this statement worries me:
I thought I passed design and started
implementing
That's old-fashioned Waterfall thinking. You never are done designing. You will almost always have to do a fairly major redesign the first time a real client tries to use your class. Thereafter every now and then you'll discover edge cases of client use that require (or would greatly benifit by) an extra new call or two, or a slightly different approach to all the calls.
You might be interested in the Interface Segregation Principle, which results in more, smaller interfaces.
"Clients should not be forced to depend on interfaces that they do not use."
More detail on this principle is provided by this paper: http://www.objectmentor.com/resources/articles/isp.pdf
This is part of the Bob Martin's synergistic SOLID principles.
There isn't a golden rule. It'll depend on the scenario, and even then you may find in the future some assumptions have changed and you need to update it accordingly.
Personally I like the way you have it now. You can replace at the top level, or very specific pieces.
Having the One Big Class That Does Everything is wrong. So is having One Big Interface That Defines Everything.