I have a library "myLibrary" that depends on "Blibrary". I want the users of "myLibrary" to not know that dependency. I'm trying to hide it without luck, here is an example of what I have right now.
#include <game/Object.h>
#include <Blibrary/Component.hpp> // How can I remove this library header?
// forward declaring it? it's a template..
namespace myLibrary {
template<typename T>
struct Component: public Object, public Blibrary::Component<T>
{
};
//template<typename T>
//class Blibrary::Component<T>; //I Tried something like that..
//template<typename T>
//struct Component: public Object
//{
// Blibrary::Component<T> * m_impl;
//};
}
//I want the user do this when declaring a usermade component:
#include <game/Component.h> //<-- but without the Blibrary include dependency
class Position: public myLibrary::Component<Position>
{
float x, y, z;
};
Is it possible to hide implementation of template class?
No, it is not. A class template must be defined completely in header files. You can only obfuscate the implementation by using multiple layers of header files and using helper class names and helper function names that are obfuscations of the highest level, user visible classes.
However, as #vsoftco noted in a comment, you can hide it if you use it only for some specific types, in which case you can do explicit instantiation, export the template and implement it in the .cpp.
A nice idea from this similar question was to put the implementation classes/functions you want to "hide" into another level of namespace.
You can even separate them into a different .h file to be included at the top.
Now, of course this is incapable of really hiding them programmatically from anywhere you include the header, but it does prevent them going into the scope, and means that it would not be possible to use them without explicitly dereferencing that additional namespace.
So for example you'd have namespace mylibrary for your library, and something like mylibrary::priv or mylibrary::impl, for example, for the things you're "hiding".
Related
I need to add a few methods to c++'s class.
I'm creating a new class using inheritance called "Super_list" that will inherit all of list's methods and allow my to add my own.
#ifndef SUPER_LIST_H
#define SUPER_LIST_H
#include "my_containter.h"
#include <list>
using namespace std;
class My_Container;
class Super_list: public list<My_Container>
{
public:
void new_func1();
void new_func2();
void new_func_3();
};
#endif
This is where I'm using my newly made class:
#ifndef my_container_H
#define my_container_H
#include <list>
#include "super_list.h"
using namespace std;
class Super_list;
class My_container
{
private:
Super_list buddy;
};
#endif
I'm getting a bunch of error relating to the inheritance not being done correctly.
I would appreciate any help or other ideas from completing this task.
Thanks :)
You have a cyclic dependency: MyContainer needs so know about Super_list and vice versa. You need to find a way to break this dependency. Note that in your code, the forward declarations are completely superfluous.
Note also that standard library containers aren't designed to be inherited from publicly.
Concerning the dependency, you need to modify at least one of your classes such that it does not need the full definition of the other. Pretending for a moment that publicly inheriting from std::list is OK, then the only option would be for My_Container not to need the full definition of SuperList by having it hold a (preferably smart) pointer:
class My_container
{
private:
Super_list* buddy;
};
This would allow you to remove the super_list.h include.
One unrelated warning: it is not good to put using namespace std in header files, since it will impose that using directive on all code that, directly or indirectly, includes your header. This can lead to all kind of trouble. I usually go farther and say you shouldn't use it anywhere. Not everyone agrees with me on that one.
I would ask if you really do need to inherit to gain additional functionality. Try using a list as a member of your class. Not only will it make your class easier to change, but it means that code that uses your class won't care about whether its a list or not.
Here is more information
Can't say much without the error messeages.
1) You probably want to define some constructors in Super_list which forward their arguments to the std::list constructors.
2) Every time I tried to do something like this (or worked with something like this) it turned out to be a BAD idea. To keep incapsulation, what you probably want is some global functions:
template<class T>
new_func1(std::list<T> &l)
template<class T>
new_func2(std::list<T> &l)
etc.
In languages like Java, you can declare a class without a modifier so it will only be visible inside the same package. I need to do something similar in C++. I am trying to create an API that will be a library to be used in other applications. After asking this question on programmers Stackexchange, I have decided to use some sort of handle, which will just be an unsigned integer that is passed to an API function, which will then pass it to a class that will look it up in some sort of table and return a pointer to the object the handle represents, back to the function. The API function will then be allowed to operate on the pointer, but without the public ever having access to the pointer.
The problem is, I would like the class that handles the handles to not be visible to the public (even though the public won't have an instance of the class that contains the handles), as it is only needed inside the API functions. Also, I wanted this handle class to be a template (only needed for compiling the API), because I would most likely have handles representing different types of classes (although I could probably get away with one table containing void pointers, but it seems a little unsafe). I cant hide the class in a .cpp file, because it would be needed in multiple .cpp files that compose the API.
Also, I was thinking about using the pimpl idiom in any classes that have public functions, that way if there were any private functions in them that needed a parameter related to one of my classes hidden from the public, a header file including hidden classes would not need to be included with the API libraries for the API user to be able to compile the program.
So what would be the best way to hide classes that are only needed among other classes (spread across multiple .h and .cpp files) inside the API its self, from the outside world?
You can indeed use the PIMPL idiom; just write a forward declaration of the type and use a (smart) pointer to it as a member. That should take care of header files.
For the implementation, just have a separate header file that is included by the implementation of the library but not by any part of the interface. Example:
// Interface.h
class Secret;
class Hi {
public:
Hi();
~Hi();
void stuff();
private:
Secret* secret;
};
// Implementation.cpp
#include "Secret.h"
#include "Interface.h"
Hi::Hi() : secret(new Secret) { }
Hi::~Hi() { delete secret; }
void Hi::stuff() { secret->stuff(); }
// Secret.h
class Secret {
public:
int data;
void stuff() { ... }
};
You don't have to hide it specifically, just don't include the internal header in the .h files that define your API.
It is perfectly normal for a project to have internal helper classes and functions that are not part of the external interface. Compile them into your library, but don't distribute the headers.
This is probably not the best solution, especially if you need to use the class in multiple classes without a common ancestor, but you could use a private or protected nested class:
class Foo {
protected:
class SecretClass {
// ...
};
// ...
};
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 9 years ago.
Normally when I create a class, I create a header and a source for that class. I have heard that with a template class, you have to put the function implementation in the header. I tried doing it both ways, and got compilation errors the first way. The second way worked fine. However, I like to organize my code into headers and source files, so is it possible to put the function implementations into a source file? (Maybe it requires special compilation flags or syntax?) Or should I just keep em in the header?
Thanks!
Generally, all template code must be in a header file since the compiler needs to know the complete type at the point of instantiation.
As Aaron says below it is possible to put the implementation details in a .cpp-file in the specific case where you know on before hand all possible types the template will be instantiated with and explicitly instantiate it with those types. You'll then get a linker error if the template gets instantiated with another type somewhere in your code.
A quite common general solution to at least visually separate interface from implementation is to put all implementation in a .inc (or .tcc or .ipp)-file and include it at the end of the header file.
Note that the syntax for putting template class members outside the class-definition (whether you use the specific solution or the general) is slightly cumbersome. You'll need to write:
// in test.h
template <class A>
class Test
{
public:
void testFunction();
};
#include "test.inc"
// in test.inc
template <class A>
void Test<A>::testFunction()
{
// do something
}
(Edited: This is slightly more robust version which allows the implementation to be compiled into a separate .o file. The template should be explicitly instantiated at the end of the implementation cpp file. Perhaps this was only an issue for g++.)
You don't need to put the implementations in the header if you know which templates will be instantiated and can list them in the header implementation file. For example, if you know that you will only use int and std::string, then you can put this in the header file:
// test.h
template <class A>
class Test
{
public:
void f();
};
and put the implementation of f() into a normal test.cpp file:
// test.cpp
#include "test.h"
template <class A> void Test<A>::f() {
// implementation
}
template class Test<int>;
template class Test<string>;
Those last two lines explicitly instantiate the template classes. It is better to put this at the end of the implementation file, after it has seen the implementations of the member functions. Then you can compile it to a .o file g++ -c test.cpp. This test.o file will contain complete implementations of both Test<int> and Test<string> and can be linked without any difficulty in the rest of your application.
It works, but is it a good idea? It depends on context. In many cases, this works very well. If you are writing a template for 'internal' use in your project, then you know which templates will be instantiated and which will not. But if instead you're making something available to the public which must be very flexible, then you will need to include the implementations in the header file.
A tip: Even if it's for public consumption, take a look at the methods and see if there are any methods whose parameters and return type are independent of the template parameters. If so, you could place them into a Base class as (pure) virtual functions. This Base class doesn't use any templates and hence you may be able to use this Base* in much of your application (template <class A> class Test : public Base { ..., allowing you to limit the reach of the templated code throughout your application. I found this useful recently when much of the underlying behaviour and construction of a class depended on the template parameters, but the interface to the already-constructed object did not depend on the template parameters.
To answer the original question: no, the definitions of [member] function templates don't have to go into the header. However, the compiler needs to see the definition to instantiate the template. For templates instantiated with many different types you want the templates to be implicitly instantiated when they are used. This is e.g. the case for class templates like std::vector<...> and for function templates like std::copy(...). In this case it is almost certainly impractical to separate the template definition from its declaration although I personally put the definitions into a separate file included at the bottom of the header file.
For templates instantiated with only a few types like the stream classes or std::basic_string<...> it is often better to define the function templates in a separate header-like file which is only included in implementation files which explicitly instantiates them. This way the effort of instantiating the template is only spent once rather than in every translation unit using it. Especially for the stream classes this makes a huge difference (primarily for compile and link time but on some systems also for executable size). ... and I'm pretty sure hardly anybody has gone to the trouble of using the stream classes with different character types than char and wchar_t (hint: it is non-trivial to arrange for the various facets to be implemented and present in the std::locale). The technique of explicitly instantiating templates also works well if there is only a limited set of types with which the template is intended to work.
While it is technically the case that you can separate your implementation from your interface the syntax for templates gets so annoying to type repeatedly I would strongly recommend that you just hold your nose and put the implementation in your class until you get over the smell.
template <class X>
class klass_t {
public:
void f();
void g();
void h();
};
template <class X>
void klass_t<X>::f() { ... }
template <class X>
void klass_t<X>::g() { ... }
template <class X>
void klasS_t<X>::h() { ... }
Would have been:
template <class X>
class klass_t {
public:
void f() { ... }
void g() { ... }
void h() { ... }
};
Now imagine you want to add another template parameter (as in the following). Now you have to change the template argument lists in n places rather than just one.
template <class X, class Y>
class klass_t {
public:
void f();
void g();
void h();
};
Unless you have a good reason not to, it is a lot easier on your fingers to just put everything in the class.
Template implementations need to be known at compile-time. That means the implementations must be visible to the compiler. There's no way to go around this.
If you want to keep implementation details a secret, there's no way to do this. You can of course obfuscate your code, but that's not much of an impediment.
If your only concern is code organization, you can create a separate include file with the implementations and include it at the end of your main header (much as Andreas' suggestion).
I am writing a C++ header in which I define a
class A {
// ...
};
that I would like to hide from the outside world (because it may change or even be removed in future versions of this header).
There is also a class B in the same header that has an object of class A as a member:
class B {
public:
// ...
private:
A a_;
};
What is a proper way of hiding class A from the outside world?
If I put the definition of A in an unnamed namespace, the compiler issues a warning, so I assume that, due to issues with internal linkage, I should do something else.
The right way to go about it in C++ is PIMPL idiom. Alternative solution is to put the class you want to hide into a nested namespace, which is usually called detail. But that will not make it totally private as users will still be exposed to its dependencies, and will be able to use it directly.
You could do an inner class:
class B
{
class A { /* ... */ };
A a_;
}
Document that this class is not part of the public API and should not be used.
In C++ you have to trusted programs that link with your library code because you have little other choice. C++ has limited "access control" features many of which can be bypassed or abused so you're better of treating your API clients with respect and building trust.
If you design your API to be easy to use correctly and hard to use unintentionally incorrectly then you will be helping your clients and it is hardly your fault if your clients abuse your interface.
An unnamed namespace is useless anyways, as it only protects agains multiple definitions. What you could do is either using the pImpl Idiom, as mentioned in other answers, or use a detail namespace. Works fine for Boost:
namespace detail{
class A{
// ...
};
}
class B{
public:
// ...
private
A a_;
};
Anyone messing with stuff in a detail namespace is asking for trouble. Or maybe obscure it even more
namespace _b_impl_detail{
// ...
};
Anyone who now touches anything inside should be shot in the foot. :)
Instead of class B holding an A object, have it hold an A* instead (or a shared_ptr<A>, or an unique_ptr<A>, etc.). This way class B only needs a forward declaration of class A and class A can be fully defined inside of class B's source file.
If A is an implementation detail of B, don't put its definition in the header at all. Instead:
class B {
...
class A * myA;
};
and then put the definition of A in the B implementation (i.e. .cpp) file.
I'd like to add a small increment over https://stackoverflow.com/a/5780976/1525238 that helped me better solve my peculiar use case, namely where the "main" class is a template and the "helper/inner" class also has to be a template1.
I used a nested namespace called detail, made all "helper" content private and made the "main" class a friend of the "helper" class:
template<__MAIN_TEMPLATE_PARAMS__> class Main;
namespace detail {
template<__HELPER_TEMPLATE_PARAMS__> class Helper {
/* All Main templates are friends */
template<__MAIN_TEMPLATE_PARAMS__> friend class Main;
/* Private stuff, not reachable from the outside */
static void privateThing(){
...
}
};
}
template<__MAIN_TEMPLATE_PARAMS__> class Main {
void usePrivateThing(){
detail::Helper<__DESIRED_HELPER_TEMPLATE_PARAMS__>::privateThing();
}
};
The private stuff is static above only to make the code shorter. They may very well be tied to the Helper instance.
In retrospect, there could certainly be more elegant solutions involving less black magic, but it highly depends on the specific application. I still find the above a legit, nice use case for a friend class.
1 This is because I needed to use a template helper function that required a partial specialization, which is not allowed yet in c++, for no particular reason but is technically possible with a wrapper class. Partial specialization is omitted from the above for simplicity.
I am using a 3rd party library that has a declaration like this:
typedef struct {} __INTERNAL_DATA, *HandleType;
And I'd like to create a class that takes a HandleType in the constructor:
class Foo
{
Foo(HandleType h);
}
without including the header that defines HandleType. Normally, I'd just forward-declare such a type, but I can't figure out the syntax for this. I really want to say something like:
struct *HandleType;
But that says "Expected identifier before *" in GCC. The only solution I can see is to write my class like this:
struct __INTERNAL_DATA;
class Foo
{
Foo(__INTERNAL_DATA *h);
}
But this relies on internal details of the library. That is to say, it uses the name __INTERNAL_DATA, which is an implementation detail.
It seems like it should be possible to forward-declare HandleType (part of the public API) without using __INTERNAL_DATA (part of the implementation of the library.) Anyone know how?
EDIT: Added more detail about what I'm looking for.
Update:
I am using it in the implementation .cpp of Foo, but I want to avoid including it in my header .h for Foo. Maybe I'm just being too pedantic? :)
Yes you are :) Go ahead with forward declaration.
If HandleType is part of the interface there must be a header declaring that. Use that header.
Your problem is still a vague one. You are trying to protect against something you cannot.
You can add the following line to your client library:
typedef struct INTERNAL_DATA *HandleType;
but, if the name/structure changes you may be in for some casting nastiness.
Try templates:
template <class T>
class Foo
{
Foo(T h);
};
Forward declaration is fine. If you are going to use pointers or references you only need a class (__INTERNAL_DATA) declaration in scope. However, if you are going to use a member function or an object you will need to include the header.
If the type is in a 3rd party library then the big benefit of forward declaration (isolating rebuilds due to changes in headers) is effectively lost.
If you're worried about compilation times (it's a sizeable header) then perhaps you can place it in a precompiled header or just include the relevant header from a library.
E.g. many library headers look like
// library.h
#include "Library/Something.h"
#include "Library/SomethingElse.h"
typedef struct {} __INTERNAL_DATA, *HandleType;
If it is defined like that (all on one line), then __INTERNAL DATA is as much a part of the public interface as HandleType.
However, I don't think __INTERNAL_DATA actually exists. More than likely, HandleType is really (internally) an int. This odd definition is just a way of defining it so that it's the same size as an int, but distinct, so that the compiler give you an error if you try passing an int where you're supposed to pass an HandleType. The library vendor could just as easily have defined it as "int" or "void*", but this way we get some type checking.
Hence __INTERNAL_DATA is just a convention and is not going to change.
UPDATE: The above was a bit of a mental burp... OK, __INTERNAL_DATA definitely does not exist. We know this for a fact, because we can see it's definition as an empty struct. I'm going to guess that the 3rd-party library uses "C" external linkage (no name managling), in which case, just copy the typedef -- it will be fine.
Inside the library itself, HandleType will have a completely different definition; maybe int, maybe "struct MyStruct {.......} *".
If you really, really, really don't want to expose _INTERNAL_DATA to the caller then your only real choice is to use typedef void* HandleType; Then inside your library you can do anything you want including changing the entire implementation of *HandleType.
Just create a helper function to access you real data.
inline _INTERNAL_DATA* Impl(HandleType h) {
return static_cast<_INTERNAL_DATA*>(h);
}
I'm not quite sure what you're going for, but the following will work without including the actual header file:
// foo.h
class Foo
{
public:
template<typename T>Foo(T* h) { /* body of constructor */ }
};
Mind you, you will still have to have access the public members of __INTERNAL_DATA within the body of the constructor.
edit: as pointed out by James Curran, the __INTERNAL_DATA structure has no members, so it can be used, as above, with no problems.