Let's say I have a header file with a class that uses std::string.
#include <string>
class Foo
{
std::string Bar;
public:
// ...
}
The user of this header file might not want std::string to be included in his/her project. So, how do I limit the inclusion to just the header file?
The user of your class must include <string>, otherwise their compiler will not know how big a Foo object is (and if Foo's constructors/destructors are defined inline, then the compiler also won't know what constructor/destructor to call for the string member).
This is indeed an irritating side-effect of the C++ compilation model (basically inherited intact from C). If you want to avoid this sort of thing entirely, you probably want to take a look at the PIMPL idiom.
Basically, you don't. Once you've included a file, all of the entities from that file are available for the remainder of the translation unit.
The idiomatic way to hide this sort of dependency is to rely on the pimpl idiom.
That said, why would code using Foo care that <string> was included? All of its entities are in the std namespace (well, except that <string> might include some of the C Standard Library headers, but generally you should code with the expectation that the C Standard Library headers might be included by any of the C++ Standard Library headers).
I don't see how this can be done, or if it's possible in c++. The reason being: when the compiler sees the member of type "std::string", it must know what is the type in order to know its size. This information can only be obtained by looking into the class definition in a .h file.
One way the users can use a different string class in their source, is by using "using" construct:
//This is how users can use an adt with same name but in different namespaces
using std::string;
string bar = "there";
using my_own_lib::string;
string bar1 = "here";
You can't do that. If the user doesn't want to include std::string, then he or she should not use that class at all. std::string will have to be included in the project in order to link your class correctly.
Related
Relatively new to cpp. When you subclass a baseclass, the #include cascade to the subclass, why don't the class-wide usings in the cpp file also cover the scope of the subclass? Is this a historical or pragmatic reason? Err.. What is the reason?
//available to subclass
#include <cinder/app/appBasic.h>
// have to duplicate in subclass
using namespace ci;
using namespace ci::app;
using namespace std;
using directive and using declaration are only valid for the current translation unit. you can put these in the header file which is not a good practice.
The main reason is that the compiler only looks at one .cpp file plus whatever it #includes. It has no idea what using statements there might be in the .cpp file for your base class. For that matter, it has no idea whether you've even written the .cpp file for the base class yet when you compile the .cpp file for the derived class. And it's not going to go rooting around the filesystem to find out, unlike for example javac.
Furthermore, I guess you're writing one .cpp file per class, and giving the file a name that has something to do with the class name. But C++ doesn't require that. You can have more than one class in a file, or for that matter you could split a class across multiple files if you want to.
So, you know that this .cpp file is the file for your derived class, and that the other .cpp file is the file for the base class, and therefore you think it might be convenient if some stuff from the other .cpp file was lifted into this .cpp file. But the compiler knows no such thing. It wouldn't make sense to the C++ compiler to talk about what's in the file for the base class.
Finally, a reason that is principled rather than pragmatic: just because it is convenient for the implementer of the base class to bring the names from certain namespaces into global scope doesn't mean the same will be true of the implementer of the derived class. The derived class might not use ci::app at all, let alone use it so much that the person writing the derived class is sick of typing it. So even if C++ could require the compiler to fetch those using statements (which, given the compilation model, it can't), I'm pretty sure the language's designers wouldn't want it to.
the #include cascade to the subclass
No they don't. Any #include in the base.h will be included into derived.cpp if (for example) derived.cpp includes derived.h which includes base.h. But any includes in base.cpp have no effect on derived.cpp.
This is all assuming that you follow the usual naming convention. There's nothing other than convention to stop you including a .cpp file from derived.cpp, in which case (1) any includes or using statements would apply in derived.cpp, but unfortunately (2) you'll probably break your build system, because most likely you won't be able to link base.o and derived.o together any more on account of them containing duplicate definitions for code entities subject to the One Defintion Rule. That is, functions.
Suppose I have a class called CameraVision in the file CameraVision.cpp.
The constructor for this class takes in a vector of IplImage* (IplImage is a C struct that represents an image in OpenCV). I need to #include opencv.h either in CameraVision.hpp or CameraVision.cpp.
Which is better and why? (#including these in CameraVision.hpp or in CameraVision.cpp?)
Also, where should I #include STL <vector>, <iostream>, etc. ?
Suppose the client of CameraVision.cpp also uses <vector> and <iostream>. The client would obviously #include CameraVision.hpp (since he is a client of CameraVision). Should the client of CameraVision.cpp also #include , <iostream>, etc. if they have already been #include'd in CameraVision.hpp? How would the client know this?
The rule here is: Limit scope. If you can get away with having the include in the implementation file only (e.g. by using a forward declaration, including <iosfwd> etc.), then do so. In public interfaces, i.e. the headers that your clients will include to use a library of your making, consider using the PIMPL pattern to hide any implementation details.
The benefits:
1) Clarity of code. Basically, when somebody is looking at a header file, he is looking for some idea of what your class is about. Every header included adds "scope" to your header: Other headers to consider, more identifiers, more constructs. In really bad code, every header includes yet more headers, and you cannot really understand one class without understanding the whole library. Trying to keep such dependencies at a minimum makes it easier to understand the interface of a class in isolation. ("Don't bother what IplImage actually is, internally, or what it can do - at this point all we need is a pointer to it").
2) Compile times. Since the compiler has to do the same kind of lookup as described in 1), the more includes you have in header files, the longer it takes to compile your source. In the extreme, the compiler has to include all header files for every single translation unit. While the resulting compile time might be acceptable for a once-over compilation, it also means that it has to be re-done after any change to a header. In a tight edit - compile - test - edit cycle, this can quickly add up to unacceptable levels.
Edit: Not exactly on-topic, but while we're at it, please don't use using in header files, because it's the opposite of limiting scope...
To avoid extra includings, you should use #include in implementation (.cpp) files in all cases, except in situations when names that you are importing, used in prototypes or declarations, which your module exports.
For example:
foo.h:
#ifndef _FOOBAR_H_
#define _FOOBAR_H_
#include <vector>
void foo();
std::vector<int> bar();
#endif // _FOOBAR_H_
foo.cpp:
#include "foo.h"
#include <iostream>
void foo() {
std::cout << "Foo";
}
std::vector<int> bar() {
int b[3] = {1, 2, 3};
return std::vector<int>(b, b+3);
}
If a type is used/referenced only within the implementation file, and not in the header file, you should #include only in the implementation file, upholding the principle of limited scope.
However, if your header file references a type, then your header file should #include that type's header file. The reason being that your header file should be able to be completely understood and have everything it needs when it is #included.
One justification for this perspective is not just for building/compiling, but also tooling. Your development environment may parse header files to provide you with type assistance (e.g. Intellisense, Command Completion, etc...) which may require complete type information to work properly.
Another justification is if your header file is used by another party, that that party has enough information about your types to make use of your code. And they should not have to #include several files to get one type to compile.
You should not #include a type's header file in another type's header file simply to avoid having to #include two files in the implementation file. Instead, a third header file should be made for the purpose of aggregating those types.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it a good idea to wrap an #include in a namespace block?
I've got a project with a class log in the global namespace (::log).
So, naturally, after #include <cmath>, the compiler gives an error message each time I try to instantiate an object of my log class, because <cmath> pollutes the global namespace with lots of three-letter methods, one of them being the logarithm function log().
So there are three possible solutions, each having their unique ugly side-effects.
Move the log class to it's own namespace and always access it with it's fully qualified name. I really want to avoid this because the logger should be as convenient as possible to use.
Write a mathwrapper.cpp file which is the only file in the project that includes <cmath>, and makes all the required <cmath> functions available through wrappers in a namespace math. I don't want to use this approach because I have to write a wrapper for every single required math function, and it would add additional call penalty (cancelled out partially by the -flto compiler flag)
The solution I'm currently considering:
Replace
#include <cmath>
by
namespace math {
#include "math.h"
}
and then calculating the logarithm function via math::log().
I have tried it out and it does, indeed, compile, link and run as expected. It does, however, have multiple downsides:
It's (obviously) impossible to use <cmath>, because the <cmath> code accesses the functions by their fully qualified names, and it's deprecated to use in C++.
I've got a really, really bad feeling about it, like I'm gonna get attacked and eaten alive by raptors.
So my question is:
Is there any recommendation/convention/etc that forbid putting include directives in namespaces?
Could anything go wrong with
diferent C standard library implementations (I use glibc),
different compilers (I use g++ 4.7, -std=c++11),
linking?
Have you ever tried doing this?
Are there any alternate ways to banish the math functions from the global namespace?
I've found several similar questions on stackoverflow, but most were about including other C++ headers, which obviously is a bad idea, and those that weren't made contradictory statements about linking behaviour for C libraries. Also, would it be beneficial to additionally put the #include <math.h> inside extern "C" {}?
edit
So I decided to do what probably everyone else is doing, and put all of my code in a project namespace, and to access the logger with it's fully qualified name when including <cmath>.
No, the solution that you are considering is not allowed. In practice what it means is that you are changing the meaning of the header file. You are changing all of its declarations to declare differently named functions.
These altered declarations won't match the actual names of the standard library functions so, at link time, none of the standard library functions will resolve calls to the functions declared by the altered declarations unless they happen to have been declared extern "C" which is allowed - but not recommended - for names which come from the C standard library.
ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] applies to the C standard library headers as they are part of the C++ standard library:
A translation unit shall include a header only outside of any external declaration or definition[*], and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.
[*] which would include a namespace definition.
Why not putting a log class in it's own namespace and using typedef namespace::log logger; to avoid name clashes in a more convenient way?
Change your class's name. Not that big of a deal. ;-)
Seriously though, it's not a great idea to put names in the global namespace that collide with names from any standard header. C++03 didn't explicitly permit <cmath> to define ::log. But implementations were chronically non-conforming about that due to the practicalities of defining <cmath> on top of an existing <math.h> (and perhaps also an existing static-link library for some headers, including math). So C++11 ratifies existing practice, and allows <cmath> to dump everything into the global namespace. C++11 also reserves all those names for use with extern "C" linkage, and all function signatures for use with C++ linkage, even if you don't include the header. But more on that later.
Because in C++ any standard header is allowed to define the names from any other standard header (i.e, they're allowed to include each other), this means that any standard header at all can define ::log. So don't use it.
The answer to your question about different implementations is that even if your scheme works to begin with (which isn't guaranteed), in some other implementation there might be a header that you use (or want to use in future in the same TU as your log class), that includes <cmath>, and that you didn't give the namespace math treatment to. Off the top of my head, <random> seems to me a candidate. It provides a whole bunch of continuous random number distributions that plausibly could be implemented inline with math functions.
I suggest Log, but then I like capitalized class names. Partly because they're always distinct from standard types and functions.
Another possibility is to define your class as before and use struct log in place of log. This doesn't clash with the function, for reasons that only become clear if you spend way too much time with the C and C++ standards (you only use log as a class name, not as a function and not as a name with "C" linkage, so you don't infringe on the reserved name. Despite all appearances to the contrary, class names in C++ still inhabit a parallel universe from other names, rather like struct tags do in C).
Unfortunately struct log isn't a simple-type-identifier, so for example you can't create a temporary with struct log(VERY_VERBOSE, TO_FILE). To define a simple-type-identifier:
typedef struct log Log;
Log(VERY_VERBOSE, TO_FILE); // unused temporary object
An example of what I say in a comment below, based on a stated example usage. I think this is valid, but I'm not certain:
#include <iostream>
#include <cmath>
using std::log; // to enforce roughly what the compiler does anyway
enum Foo {
foo, bar
};
std::ostream &log(Foo f) { return std::cout; }
int main() {
log(foo) << log(10) << "\n";
}
It is ugly hack too, but I believe will not cause any linker problems. Just redefine log name from <math.h>
#define log math_log
#include <math.h>
#undef log
It could cause problems with inline functions from math using this log, but maybe you'd be lucky...
Math log() is still accessible but it's not easy. Within functions where you want to use it, just repeat its real declaration:
int somefunc() {
double log(double); // not sure if correct
return log(1.1);
}
I am writing a utility library which is made up of several "Packages". The classes in each package are contained in various namespaces. I have an idea as to how I can simplify the situation by automatically declaring using statements at the end of class declarations (see below), this will avoid having the programmer do it in a cpp file.
namespace Utility
{
class String
{
// Class Implementation
};
}
using Utility::String;
My understanding is that if the user includes the header String.h and String is in Utility then the programmer will want to use String. Obviously this could be bad if there are outside classes chain including a bunch of files which dirty up the namespace so I thought how about making it a #define instead.
namespace Utility
{
class String
{
// Class Implementation
};
}
#ifdef AUTO_DECLARE_NAMESPACE
using Utility::String;
#endif
That way, programmers that want this extended functionality can get it.
Would this a good idea or is there something I'm overlooking?
There is no point in using namespaces if you are just going to add a using declaration for each and every name declared in the namespace.
Let users of your header files decide how they want to use the headers. If someone wants to use a using declaration, let him do it in the .cpp file directly; this will make the code in that .cpp file clearer since it will be apparent where the name originated.
This seems at best pointless, and at worst annoying.
What is wrong with having developers decide which namespaces to use and what to qualify fully?
Honestly, I believe that's what the using namespace directive is for. There's no need for you to add this preprocessor mechanism, considering the using namespace directive does just that.
Couldn't you have another .h file with all your usings like my_lib_import_names.h and just #include that to get what you want?
You would probably have problem with classes not being declared but you could probably bypass it by using something like:
#ifdef UTILITY_STRING_H_
using Utility::String;
#endif
..
#ifdef UTILITY_SOMETHING_ELSE_H
using Utility::SomethingElse;
#endif
..
What do you think?
That way you could retain the "expected" behavior in your library .h but also have your the way you like. You also get to keep the benefit of the namespace over your classes (at the expense of having to maintain your new .h file).
I am new to c/c++, I am confused about followings:
Whether I should put class declarations in its own header file, and actual implementation in another file?
Whether I should put headers like <iostream> in the example.h file or in example.cpp file?
If all the classes need to use <iostream>, and I include a class's header file into another class's header, does it mean I included <iostream> twice?
If I use a lot STL classes, what is a good practice to use std::?
1.Whether I should put class declarations in its own header file,
and actual implementation in another
file?
You can write the definition of a class, and the definition of the members of the class separately in the same header file if you are manipulating templates. Also, if you want to make your members function inline, you can define them inside the class definition itself. In any other case, it is better to separate the definition of the class (.hpp file) and the definition of the members of the class (.cpp).
2.Whether I should put headers like in the example.h file or in example.cpp
file?
It Depends on if you need those headers in the example.h file or in your .cpp file only.
3.If all the classes need to use , and I include a class's header file into
another class's header, does it mean I
included twice?
It happens if you don't wrap your class definitions by the following macros:
#ifndef FOO_HPP
#define FOO_HPP
class {
...
};
#endif
5.If I use a lot STL classes, what is a good practice to use std::?
I think it is better whenever you can to use std:: each time instead of using namespace std. This way you will use only the namespaces that you need and your code will be more readable because you will avoid namespace conflicts (imagine two methods that have the same name and belong to two different namespaces).
But most importantly where is question number 4 anyway?
Generally, yes. It helps with organization. However, on small projects it may not be that big of a deal.
I'm having trouble understanding the question here. If you're asking where to put the #include directive, the implementation file should include the header file.
Yes, but the use of include guards prevents multiple inclusions.
You normally should, but for relatively small projects you may avoid having an implementation file as much as possible;
If your header is using only incomplete types from the <iostream>, you can avoid including it, but you'll need forward declarations for these types (see When to use forward declaration?). Yet, for simplicity, if the type uses template, I normally include the respective header;
No. The include guards guarantee that a header is included only once in the same translation unit;
A common good practice is to not put using namespace std in a header file. Be aware of namespace conflicts too;
Typically, you do put class declarations (including declarations of members) into header files and definitions of member functions (methods) in source files. Headers usually have names like *.h or *.hpp. As to point 3, you should put include guards into your headers so they can be safely included multiple times in the same source file; then you can include them everywhere you need them. I don't understand point #5: are you asking about when to use std:: namespace qualification?
For the "included twice" problem, here is a common pattern for your header files:
// _BLAHCLASS_H_ should be different for each header, otherwise things will Go Bad.
#ifndef _BLAHCLASS_H_
#define _BLAHCLASS_H_
... rest of header ...
#endif
As long as they're not templates, generally yes. Templates (for better or worse) have to be put in headers.
I prefer to make each of my headers "standalone", so if any other header is needed for it to function, it includes that header itself (e.g., if I have a class that uses std::string, the header for that class will #include <string>.
No. With a few special exceptions, the standard headers are required to be written so you can include them more than once without it changing anything (the primary exception is assert.h/cassert, which it can make sense to include more than once).
I'm not sure exactly what you're asking. If you're asking about a using directive like using namespace std;, then it's generally (though certainly not universally) disliked. A using declaration like using std::vector; is generally considered less problematic.