This question already has answers here:
Is it possible to avoid repeating the class name in the implementation file?
(8 answers)
Closed 6 years ago.
If in C++ I have a class longUnderstandableName. For that class I have a header file containing its method declaration. In the source file for the class, I have to write longUnderstandableName::MethodA, longUnderstandableName::MethodB and so on, everywhere.
Can I somehow make use of namespaces or something else so I can just write MethodA and MethodB, in the class source file, and only there?
typedef longUnderstandableName sn;
Then you can define the methods as
void sn::MethodA() {}
void sn::MethodB() {}
and use them as
sn::MethodA();
sn::MethodB();
This only works if longUnderstandableName is the name of a class. It works even if the class is deeply embedded in some other namespace.
If longUnderstandableName is the name of a namespace, then in the namespace (or source file) where you want to use the methods, you can write
using namespace longUnderstandableName;
and then call methods like
MethodA();
MethodB();
You should be careful not to use a using namespace foo; in header files, because then it pollutes every .cpp file that we #include the header file into, however using a using namespace foo; at the top of a .cpp file is definitely allowed and encouraged.
Inside the methods of the classes, you can use the name without qualification, anyway: just drop the longUnderstandableName:: prefix.
In functions inside the class source file that are not methods, I suggest to introduce file-scope static inline functions, like so:
inline type MethodA(type param){
return longUnderstandableName::MethodA(param);
}
Then you can call MethodA unqualified; due to the inline nature, this likely won't cost any runtime overhead.
I'm not sure I'd recommend it, but you could use a macro like:
#define sn LongUnderstandableName
void sn::MethodA(parameters) { ... }
int sn::MethodB(parameters) { ... }
and so on. One of the bad points of macros is that they don't respect scope, but in this case, the scope you (apparently) want is the source file, which happens to correspond (pretty closely) with the scope of a macro.
Well, yes, once you understand namespaces.
Instead of naming your class MyBonnieLiesOverTheOcean, instead set up the following:
namespace My { namespace Bonnie { namespace LiesOverThe {
class Ocean { ... };
} } }
Now, when defining your methods, you put the same namespaces around the whole file, and you write:
Ocean::SomeMethod() ...
When using the class from outside all the namespaces, it's:
My::Bonnie::LiesOverThe::Ocean
If you need to reference a lot of things from some other namespace in some source file, you can use the 'use' directive to ditch the prefixes.
Related
I am developing a project in which I have a vendor library, say vendor.h, for the specific Arduino-compatible board I'm using which defines class HTTPClient that conflicts with an Arduino system library, HTTPClient.h, which also defines class HTTPClient.
These two classes are unrelated other than having the same name, and the vendor implementation of an HTTP client is far less capable than the Arduino system library's implementation, so I'd prefer to use the latter. But I can't omit including the former, because I need quite a bit from the vendor.h. Essentially, I have the problem posed here, but with classes rather than functions. I have the full code of both, but given that one is a system library and the other is a vendor library, I'm reluctant to fork and edit either, as that adds lots of merging work down the road if either of them are updated, so my preference would be to find a tidy solution that doesn't edit either header.
I've tried a variety of solutions posted in other SO questions:
I do not want to leave out either header, as I need vendor.h for quite a few things and need the capabilities of HTTPClient.h's client implementation
Proper namespaces in the headers would solve the problem, I would prefer to avoid editing either header
I tried wrapping the #include <HTTPClient.h> in a namespace in my main.cpp, but that caused linking errors, as it's not a header-only library, so the header & cpp weren't in the same namespace
I tried a simple wrapper as proposed for the function in the above linked SO question in which the header contained just a forward declaration of my wrapper class & the associated cpp contained the actual class definition. This gave a compiler error of error: aggregate 'HTTP::Client client' has incomplete type and cannot be defined (Code sample of this attempt below)
main.cpp:
#include <vendor.h>
#include "httpclientwrapper.h"
HTTP::Client client;
httpclientwrapper.h:
#ifndef INC_HTTPCLIENTWRAPPER_H
#define INC_HTTPCLIENTWRAPPER_H
namespace HTTP {
class Client;
}
#endif
httpclientwrapper.cpp:
#include "httpclientwrapper.h"
#include <HTTPClient.h>
namespace HTTP {
class Client : public ::HTTPClient {};
}
In that example, I can't inherit from HTTPClient in a class definition in my header, as that will reintroduce the duplicate class name to the global namespace in my main program (hence the perhaps misguided attempt to see if a forward declaration would do the trick). I suspect that I can resolve the issue by completely duplicating the class definition of HTTPClient in my wrapper class above rather than trying to use inheritance. I would then add member definitions to my wrapper cpp which pass the call to HTTPClient's members. Before I go through the trouble of rewriting (or more likely, copy/pasting) the entire HTTPClient definition from HTTPClient.h into my own wrapper, I was wondering if there was a better or more proper way to resolve the conflict?
Thanks for you help!
As a solution was never proposed, I'm posting an answer that summarizes my research and my ultimate resolution. Mostly, I encourage the use of namespaces, because proper uses of namespaces would have eliminated the conflict. However, Arduino environments try to keep things simple to lower the barrier of entry, eschewing "complicated" features of C++, so more advanced use cases will likely continue to run into issues like this. From other SO answers and forum posts (cited where I could), here are some methods for avoiding name conflicts like this:
If you can edit the source
Edit the source code to remove the conflict or add a namespace to one of both libraries. If this is an open source library, submit a pull request. This is the cleanest solution. However, if you can't push your changes back upstream (such as when one is a system library for some hardware), you may end up with merge issues down the road when the maintainer/developer updates the libraries.
If you can't edit the source
Credit for part of this: How to avoid variable/function conflicts from two libraries in C++
For libraries that are header only libraries (or all functions are inline)
(ie, they have only a .h file without a .o or .cpp)
Include the library inside a namespace. In most code, this is frowned upon as poor form, but if you're already in a situation where you are trying to cope with a library that doesn't contain itself nicely, it's a clean and simple way to contain the code in a namespace and avoid name conflicts.
main.cpp
namespace foo {
#include library.h
}
int main() {
foo::bar(1);
}
For libraries with functions
The above method will fail to link at compile time, because the declarations in the header will be inside the namespace, but the definitions of those functions are not.
Instead, create a wrapper header and implementation file. In the header, declare your namespace and functions you wish to use, but do not import the original library. In the implementation file, import your library, and use the functions inside your new namespaced functions. That way, the one conflicting library is not imported into the same place as the other.
wrapper.h
namespace foo {
int bar(int a);
}
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
int bar(int a) {
return ::bar(a);
}
}
main.cpp
#include "wrapper.h"
int main() {
foo::bar(1);
}
You could also, for the sake of consistency, wrap both libraries so they're each in their own namespace. This method does mean that you will have to put in the effort to write a wrapper for every function you plan to use. This gets more complicated, however, when you need to use classes from the library (see below).
For libraries with classes
This is an extension of the wrapper function model from above, but you will need to put in more work, and there are a few more drawbacks. You can't write a class that inherits from the library's class, as that would require importing the original library in your wrapper header prior to defining your class, so you must write a complete wrapper class. You also cannot have a private member of your class of the type from the original class that you can delegate calls to for the same reason. The attempt at using a forward declaration I described in my question also did not work, as the header file needs a complete declaration of the class to compile. This left me the below implementation, which only works in the cases of a singleton (which was my use case anyway).
The wrapper header file should almost completely duplicate the public interface of the class you want to use.
wrapper.h
namespace foo {
Class Bar() {
public:
void f(int a);
bool g(char* b, int c, bool d);
char* h();
};
}
The wrapper implementation file then creates an instance and passes the calls along.
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
::Bar obj;
void Bar::f(int a) {
return obj.f(a);
}
bool Bar::g(char* b, int c, bool d) {
return obj.g(b, c, d);
}
char* Bar::h() {
return obj.h();
}
}
The main file will interact with only a single instance of the original class, no matter how many times your wrapper class in instantiated.
main.cpp
#include "wrapper.h"
int main() {
foo::Bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
Overall, this strikes me as a flawed solution. To fully wrap this class, I think the this could be modified to add a factory class that would be fully contained inside the wrapper implementation file. This class would instantiate the original library class every time your wrapper class is instantiated, and then track these instances. In this way, your wrapper class could keep an index to its associated instance in the factory and bypass the need to have that instance as its own private member. This seemed like a significant amount of work, and I did not attempt to do so, but would look something like the code below. (This probably needs some polish and a real look at its memory usage!)
The wrapper header file adds a constructor & private member to store an instance id
wrapper.h
namespace foo {
Class Bar() {
public:
Bar();
void f(int a);
bool g(char* b, int c, bool d);
char* h();
private:
unsigned int instance;
};
}
The wrapper implementation file then adds a factory class to manage instances of the original library's class
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
class BarFactory {
public:
static unsigned int new() {
instances[count] = new ::Bar();
return count++;
}
static ::Bar* get(unsigned int i) {
return instances[i];
}
private:
BarFactory();
::Bar* instances[MAX_COUNT]
int count;
};
void Bar::Bar() {
instance = BarFactory.new();
}
void Bar::f(int a) {
return BarFactory.get(i)->f(a);
}
bool Bar::g(char* b, int c, bool d) {
return BarFactory.get(i)->g(b, c, d);
}
char* Bar::h() {
return BarFactory.get(i)->h();
}
}
The main file remains unchanged
main.cpp
#include "wrapper.h"
int main() {
foo::bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
If all of this seems like a lot of work, then you're thinking the same thing I did. I implemented the basic class wrapper, and realized it wasn't going to work for my use case. And given the hardware limitations of the Arduino, I ultimately decided that rather than add more code to be able to use the HTTPClient implementation in either library, I wrote my own HTTP implementation library in the end, and so used none of the above and saved several hundred kilobytes of memory. But I wanted to share here in case somebody else was looking to answer the same question!
Most classes appear to be separated between declaration and definition in the following form using namespace qualifier to define the class:
// test.h
class test
{
public:
void func1(void);
private:
void func2(void);
};
// test.cpp
void test::func1(void)
{
//whatever
}
void test::func2(void)
{
//whatever
}
Why don't we typically see people use the keyword class in the .cpp file? Like in the following form:
// test.cpp
class test {
void func1(void)
{
//whatever
}
void func2(void)
{
//whatever
}
};
Is it just convention to use the namespace qualifiers? Or because it make more sense when you starting implementing a class via multiple source files?
Let's view this question from another angle...
It is possible to use the same syntax for both, but it's "the other one"; the following is perfectly valid:
namespace ns
{
int foo();
}
int ns::foo() { return 0; }
Looked at like this, it's the opposite question that's interesting, "why is it common to include the word 'namespace' in .cpp files?"
There's one substantial difference between namespaces and classes that makes namespace {} necessary in so many places: namespaces are open to extension, but classes are defined entirely by their (one and only) definition.
Like with classes, you can't add anything to a namespace using the syntax above; you can't add a function bar above with only int ns::bar() { return 9; }, the only way to add names to a namespace is "from within".
And, as many have discovered, it's convenient to wrap an entire file in a namespace and not use the qualified names, even if you're not adding any names to it.
Hence the popularity of "namespace": it's a convenience enabled by the extensibility of namespaces.
Another issue is that the meaning of your "test.cpp" would depend on whether the class definition has already been seen by the compiler – without it, that's a valid and complete definition of a class with two private functions.
This kind of "action from a distance" depending on possibly very distant code is painful to work with.
It's also worth noting that namespaces were added some twenty years after "C with classes" was created, when C++ was a well established language, and changing the meaning of a construct that literally hasn't changed in decades is pretty much unthinkable.
Partularly if all it does is save a few keystrokes.
I am familiar with the following use of namespaces.
In the header file (for example people.h) I describe interface of a name space. For example:
namespace people{
int getAge(str Name);
void setName(str Name);
}
Then in people.cpp I define the methods from the space name:
#include "people.h"
int people::getAge(str Name) {
something_1;
something_2;
}
void people::setName(str Name) {
something_1;
}
However, in a header file that I have I see that in addition to the namespace people there are also interfaces of other namespaces (for example namespace dogs). And these name spaces are not defined in the people.cpp file.
So, I assumed that (because of some strange reason) the interface for the namespace dogs is put into the people.h and then then the name space dog is defined in the "dogs.cpp" file. So, in other words I assumed that two different name spaces are defined in two different cpp files but their interface is described in one header file. However, this assumption seems to be wrong because I found that there are many header files that declare "namespace dogs".
So, I assume that namespace dogs in the 2people.h" file has another function but I cannot figure out what function it is. Could anybody please help me with that?
ADDED
The code that I try to understand is written not by me and it works fine. So, it should make sense. May be I was not clear enough. So, I try to give an example:
In the header file (people.h) I have:
namespace etet
{
class date;
}
namespace xsystem{
class estimation_module;
}
namespace people {
a_lot_of_different_stuff;
}
Then the people.cpp defines all the methods that belong to the people name space.
The "namespace interface" is a misleading concept. A namespace is just a bounch of names grouped together under a surname (like you and your brothers and sisters). It has no "interface" because there is no namespace "obejct".
The
#include "people.h"
int people::getAge(str Name) {
something_1;
something_2;
}
void people::setName(str Name) {
something_1;
}
is perfectly equivalent to
#include "people.h"
namespace people
{
int getAge(str Name) {
something_1;
something_2;
}
void setName(str Name) {
something_1;
}
}
may be this is more familiar, or may be not.
The fact an header declares functions not present in a cpp, just means they are probably present in another one.
About the fact that the namespace name { ..... } declaration can be repeated in many files, each containing various function is perfectly normal, since the namespace keyword does not declare an object. It just group names. And -in fact- sayning a namespace is "declared" is a common language abuse. What is declared is the name of the namespace.
And different names declare in different places can belong to a same group. there is nothing mysterious in that.
You lexicon makes me thinking you are confusing namespaces with classes and structs
ADDED:
After your clarification, it looks like the a_lot_of_different_stuff contains declarations that use etet::date and xsystem::estimation_module;
This names (and only the names) must be known to the compiler, but the header cannot recursively include ther respective headers because they most likely already included people.h.
A typical "curculare reference" problem, like in here, but involving different namespaces.
You're confusing namespaces and classes. Typically, a class definition occurs in a header file (.h) and the implementation of its member functions appear in the corresponding implementation file (.cpp).
A namespace works differently to a class. If a class is defined in multiple translation units, it must have precisely the same tokens in all of them. You can't even reorder members, even if it would result in the exact same class. It's easy to meet this requirement by using the above described header files. Each translation unit that needs a class foo contains the contents of foo.h because they do #include "foo.h" when they need it. Of course they all contain precisely the same definition of foo bceause they all included foo.h.
However, this is very different to namespaces. A namespace can be introduced multiple times across the same and different translation units without it being the same tokens every time. Something like this is totally fine:
namespace bar {
void baz();
struct x;
}
// some stuff
namespace bar {
void do_something(x);
}
Each occurence of namespace bar introduces some declarations to that namespace.
You will often have many classes defined in the same namespace. Each header for those classes will do namespace whatever { ... } and introduce the class definition into that namespace.
Sometimes you will even want to introduce things to multiple namespaces or nested namespaces in a single header file. There's nothing to stop you doing that. A possible situation for doing that is if you want to forward declare something from another namespace. Let's say you have a class defined in people.h like so:
namespace people {
class person {
dogs::dog* pet_dog;
};
}
Now, this class needs to know about the type dog in the dogs namespace. One way to do his would be to #include "dogs.h". However, since pet_dog is only a pointer, we can do with an incomplete type, so we can forward declare dog like so:
namespace dogs {
class dog;
}
namespace people {
class person {
dogs::dog* pet_dog;
};
}
Let's say the Acme company releases a useful library with an extremely ugly C API. I'd like to wrap the structs and related functions in C++ classes. It seems like I can't use the same names for the wrapper classes, because the original library is not inside a namespace.
Something like this is not possible, right?
namespace AcmesUglyStuff {
#include <acme_stuff.h> // declares a struct Thing
}
class Thing {
public:
...
private:
AcmesUglyStuff::Thing thing;
};
Linking will be a problem.
The only way I can think to wrap the library, and not pollute my namespace with the C library names, is a hack like this, reserving space in the class:
// In mything.h
namespace wrapper {
class Thing {
public:
...
private:
char impl[SIZE_OF_THING_IN_C_LIB];
};
}
// In thing.cc
#include <acme_stuff.h>
wrapper::Thing::Thing() {
c_lib_function((::Thing*)impl); // Thing here referring to the one in the C lib
}
Is that the only way? I'd like to avoid putting prefixes on all my class names, like XYThing, etc.
Seems like you're making this harder than it needs to be.
#include "acme_stuff.h" // puts all of its names in global namespace
namespace acme {
class Thing {
public:
// whatever
private:
::Thing thing;
};
}
Now just use acme::Thing rather than Thing.
If it's really important to you to not have the C names in the global namespace, then you need a level of indirection:
namespace acme {
class Thing {
public:
Thing();
~Thing();
// whatever
private:
void *acme_thing;
};
}
In your implementation file, #include "acme_stuff.h", in your constructor create a new ::Thing object and store its address in acme_thing, in your destructor delete it, and in your member functions cast acme_thing to type ::Thing*.
It's not a good idea to try to name something the exact same thing as something else. (I mean equal fully-qualified names, including all namespaces.) If some library has already grabbed the obvious best name in the global namespace, you'll need to pick a different name.
You could put your class Thing in a namespace as Pete Becker suggests, and then use ::Thing to access Acme's Thing. That would be fine if you're prepared to always access your class through it's fully namespace-qualified name (e.g. My::Thing). It's tempting to try using My::Thing; or using namespace My;, but that won't work, because any translation unit that includes the definition of your class (e.g. via a header file you create) must necessarily pull Acme's Thing into the global namespace first (otherwise an "Undefined symbol" compilation error would occur when parsing the definition of My::Thing).
Is it really a C API? Try to extern "C" {} to whole included header to solve the linking problem.
namespace AcmesUglyStuff {
extern "C" {
#include <acme_stuff.h>
}
}
I currently have a project with 3 files.
One DBheader.h header file that includes:
Class declarations (with their smaller member function definitions)
A DBdefinitions.cpp file with:
Larger member function definitions for the classes in DBheader.h
and finally a DBmain.cpp file that contains:
Main code
Some large (non-memeber) functions that use the classes defined in DBheader.h
I would preferably like to move these functions somewhere to make my DBmain.cpp file less cluttered. Should/could I move them to the DBdefinition.cpp file or do I need to create a new separate .cpp file for non-member functions?
Here's a rough of what my code looks like if the above is unclear.
//DBheader.h
//libraries..
class course{
//member data..
void printinfo();
}
-
//DBdefinitions.cpp
#include "DBheader.h"
void course::printinfo(){/*do stuff*/}
-
//DBmain.cpp
#include "DBheader.h"
typedef map<int,course> record;
void fileinput(record &map);
int main(){
//stuff
}
void fileinput(record &map){
//lots of code
}
You should organize free functions that are part of the public interface in a similar fashion you used for the class definition: a header with the declaration and an implementation file with the implementations.
If they are particular to a specific translation unit, keep them in that implementation file.
All free functions should be declared inside a namespace (named for the public ones, anonymous for "private" free functions).