Hide contents of third-party C++ header file - c++

I'm creating a static library in C++ to define a class that others can use in their code. However, a member of the class is of a type defined in a header file obtained from someone else, and I don't want to distribute the contents of this person's header file.
Here is the current public interface (interface.h):
class B {
TypeToHide t;
// other stuff ...
};
class A {
double foo();
B b;
};
And here is the code that will be compiled into a static library (code.cpp):
double A::foo() {
// ...
}
And here is the file whose contents I need to hide from public view (HideMe.h):
struct TypeToHide {
// stuff to hide
};
What can I do hide the contents of HideMe.h? Ideally, I could just stick the entire struct from HideMe.h into code.cpp.

You can use the PIMPL idiom (Chesshire Cat, Opaque Pointer, whatever you want to call it).
As the code is now, you can't hide the definition of TypeToHide. The alternative is this:
//publicHeader.h
class BImpl; //forward declaration of BImpl - definition not required
class B {
BImpl* pImpl; //ergo the name
//wrappers for BImpl methods
};
//privateHeader.h
class BImpl
{
TypeToHide t; //safe here, header is private
//all your actual logic is here
};

Simpler than Pimpl, you can use a pointer to TypeToHide and a forward declaration for it:
class B {
TypeToHide* t;
// other stuff ...
};
As long as you won't need knowledge about t's internal structure for the user's code, you won't have to expose it and it will stay safe in your library.
The code inside the library will have to know what TypeToHide is, but that's not a problem.

Related

Can you use the pimpl idiom for use across multiple cpp files with one class?

For instance, here is what I mean. Let's say you have a single header file with a single pimpl class. Can you define the functions of this class across two cpp files without redefining the variables of the class?
I've tried this before using a static variable for the pointer and a redefinition in both files. I keep running into issues regarding class variables being erased when moving across files, however.
//Header
class PRIVATE {
struct Test2;
public:
struct Test;
std::shared_ptr<Test> Client_ptr;
PRIVATE();
}; //PRIVATE
static std::shared_ptr<PRIVATE> PB = std::shared_ptr<PRIVATE>();
//Cpp1
//Implementation for Private
//Implementation for Test1
//Function not inside either class, references PB, defined in Cpp2 -> READ ACCESS VIOLATION
//Cpp2
//Definition Goes Here
//Implementation for Test2
//Function not inside either class, references PB, defined in Cpp1 -> READ ACCESS VIOLATION
Usually with this kind of thing, you'd have a public header, e.g.
#pragma once
class Foo {
Foo();
~Foo();
private:
struct FooPimpl;
FooPimpl* pimpl;
};
Then you'd have a second private header file (typically in your source directory, rather than include dir). The private header would define your Pimpl struct type.
#pragma once
struct Foo::FooPimpl {
/*stuff*/
};
You'd need to declare your ctors / dtors somewhere, e.g.
Foo.cpp
#include "public/Foo.h"
#include "./Foo.h"
Foo::Foo() {
pimpl = new FooPimpl;
}
Foo::~Foo() {
delete pimpl;
}
And you can use that same pattern (e.g. include public header, then private header) for all your other source files.
One issue with splitting pimpl internals across separate compilation units is that you need at least one compilation unit that knows how to destroy all members.
For example:
//main.h
class Main {
struct Test;
struct Test2;
std::unique_ptr<Test> pimpl1;
std::unique_ptr<Test2> pimpl2;
public:
Main();
~Main();
};
//test1.cpp
struct Main::Test {
};
// we don't know what Test2 is, so we cannot define Main::~Main().
//test2.cpp
struct Main::Test2 {
};
// we don't know what Test is, so we cannot define Main::~Main().
One solution is this:
class Main {
struct Test;
struct Test2;
std::unique_ptr<Test> pimpl1;
struct Defer {
std::unique_ptr<Test2> pimpl2;
Defer();
~Defer();
};
Defer defer;
public:
Main();
~Main();
};
Now, Main::Defer::~Defer() can live in test2.cpp where it knows how to destroy its pimpl2 instance but doesn't need to know how to destroy pimpl. Similarly, since Main::Defer is defined (not just declared) in main.h, Main::~Main() can properly destroy its defer member:
//test1.cpp
/* Test definition */
Main::Main() : pimpl(std::make_unique<Test>()), defer() {}
Main::~Main() {}
//test2.cpp
/* Test2 definition */
Main::Defer::Defer() : pimpl2(std::make_unique<Test2>()) {}
Main::Defer::~Defer() {}
It's still difficult to have Test and Test2 talk between each other but that is kind of the point of pimpl. It can be facilitated by Main offering some interfaces or by some intermediate header that declares some interfaces.

Private class name abbreviation techniques?

My class uses the PImpl idiom and looks something like this:
// In LongDescriptiveClassName.hpp
class LongDescriptiveClassName
{
public:
// Stuff...
private:
struct LongDescriptiveClassNameData;
LongDescriptiveClassNameData &Data;
};
In the .cpp file, I declare/define the private struct:
// In LongDescriptiveClassName.cpp
struct LongDescriptiveClassName::LongDescriptiveClassNameData
{
void PrivateMethod1();
void PrivateMethod2();
// and so on...
};
void LongDescriptiveClassName::LongDescriptiveClassNameData::PrivateMethod1()
{
// Stuff...
}
void LongDescriptiveClassName::LongDescriptiveClassNameData::PrivateMethod2()
{
// Stuff...
}
This is painful for me to read. Is there a way that I can abbreviate the names leading up to the private methods?
My understanding is that I can't typedef it in the .cpp file because the PImpl struct is private. Would it be an evil to use #define?
#define ShortName LongDescriptiveClassName::LongDescriptiveClassNameData
struct ShortName
{
// ...
};
void ShortName::PrivateMethod1()
// ...
This .cpp file is the only source file that would need to abbreviate it, and then only for method definitions. What do you recommend?
The class name is already a namespace, so there's no reason to give the impl such a long name:
class LongDescriptiveClassName
{
public:
// Stuff...
private:
struct Impl;
// shared_ptr is also an option if that's
// the semantics you want.
std::unique_ptr<Impl> Data;
};
// and off in the implementation, we have...
struct LongDescriptiveClassName::Impl
{
void PrivateMethod1();
void PrivateMethod2();
// and so on...
};
void LongDescriptiveClassName::Impl::PrivateMethod1()
{
// Stuff...
}
It works just fine.
Incidentally, your code is not an example of the pimpl idiom. The "p" in "pimpl" means "pointer", and this is important. A reference means that the object does not own its implementation.
It's not necessarily wrong; there are sometimes good reasons to wrap a reference in a class, but it's not the pimpl idiom.
I'm not completely sure to understand your problem but it seems that a proper use of the using keyword should help a lot. Isn't
using ShortName = LongDescriptiveClassName::LongDescriptiveClassNameData
what you are looking for ?
Note this only work is LongDescriptiveClassNameData is a type not a data.
While #Pseudonym's solution is absolutely fine, I prefer to use names with initial upper case only for types, so I think I'd just do:
class LongDescriptiveClassName {
private:
struct Data;
Data &data;
};
I like to call it Impl, or Detail (though the latter is common as a namespace detail, also).

Typedef private struct prototype in source file

In my class I have the need to keep a pointer to a structure which is defined in a library I use to implement it. Since this library is only used within the implementation file I would like to avoid including it in the header directly. At the same time I want to avoid polluting the namespace. Thus I would like to do:
/* HEADER */
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p;
};
/* SOURCE */
#include <Library.h>
using Foo::ImplementationDetail = Library::SomeStruct;
But this doesn't work, and I'm currently falling back on PIMPL:
/* HEADER */
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p_;
};
/* SOURCE */
#include <Library.h>
struct ImplementationDetail {
Library::SomeStruct * realp_;
}
Is there a way to avoid the double dereference? Is the reason for my non-working first solution due to unknown pointer sizes?
// Header
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p;
};
// Source
#include <Library.h>
struct Foo::ImplementationDetail :public Library::SomeStruct {
// ....
};
and allocating/deallocating/dereferencing the pointer in this source file only should work just fine.
This is an incorrect declaration:
using Foo::ImplementationDetail = Library::SomeStruct;
using doesn't work this way. In C++11 using cannot create an alias for a name in one namespace to a name in another namespace. In C++03, all using does is bring some other namespace in to global visibility in the current translation unit. It's not used to create aliases in C++03, as you seem to want to do here.
pimpl is the de-facto method for doing what you're trying to do, but in your header file instead of trying to use a ImplementationDetail*, I would use a simple void*. Using a void* in this manner is guaranteed to be correct according to the Standard:
class Foo {
private:
void * pImpl;
Use static_cast2 to go from a void* to your actual type:
void Foo::Bar()
{
Library::SomeStruct* thingy = static_cast <Library::SomeStruct*> (pImpl);
// ...
}
You can avoid using the void* in a conformant way by forward-declaring your library type:
namespace Library
{
struct SomeStruct;
};
class Foo
{
private:
Library::SomeStruct* pStruct;
};
And then no ugly cast is needed in the implementation.
2 Use static_cast : Or reinterpret_cast
The reason you can't take your first approach is that in the header you tell the compiler "I'm declaring a nested class within Foo and it's called ImplementationDetail". Then you proceed to say "wait wait, it's NOT a new class, it's an alias to this other thing entirely" and understandably the compiler gets confused.
Have you tried just forward declaring the library's implementation and using that instead of trying to create an alias?
In your first code you declared the nested type ImplementationDetail to be a struct which will be define inside Foo. Trying to alias it can't work because that would be a type defined elsewhere and, actually, you private structure isn't accessible from outside the class. Wrapping a pointer to another object inside seems unecessary: you could instead either embed the Library::SomeStruct by value or have your ImplementationDetail derive from Library::SomeStruct:
struct ImplementationDetail
: Library::SomeStruct {
using Library::SomeStruct::SomeStruct;
};
(the using declaration is just used to inherit all the constructors from Library::SomeStruct).
I think this is not possible without casting.
Basically there are two ways to do it:
1) Define p_ as void* and cast it in every function that uses it.
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
void Foo::AnyFunc()
{
Library::SomeStruct* pImpl = reinterpret_cast<Library::SomeStruct*>(p);
...
}
2) Create a "shadowing"-class of your class (in the .cpp-file) with all members cloned and p_ defined as Library::SomeStruct. Then cast the this-pointer to this shadowing class. This is of course a quite insecure and dirty hack which I don't recommend...
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
class FooImpl
{
public:
void AnyFunc() { p->DoSomething(); }
private:
Library::SomeStruct* p;
}
void Foo::AnyFunc()
{
FooImpl* pImpl = reinterpret_cast<FooImpl*>(this);
pImpl->AnyFunc();
}
This exploits memory structure and is therefore quite fragile (all members need to be in the same order and when you add or remove members, you need to update ShadowFoo, too). I mentioned this just for completeness.
3) This brings us to yet another, but more simple way: create the implementation in the source file and initialize it in the constructor with the void*-pointer:
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
class FooImpl
{
public:
FooImpl(void* pSomeStruct)
{
p = reinterpret_cast<Library::SomeStruct*>(pSomeStruct);
}
void AnyFunc() { p->DoSomething(); }
private:
Library::SomeStruct* p;
}
void Foo::AnyFunc()
{
FooImpl impl = FooImpl(p);
impl.AnyFunc();
}

C++ method declaration, class definition problem

I have 2 classes: A and B. Some methods of class A need to use class B and the opposite(class B has methods that need to use class A).
So I have:
class A;
class B {
method1(A a) {
}
}
class A {
method1(B b) {
}
void foo() {
}
}
and everything works fine.
But when I try to call foo() of class A from B::method1 like this:
class B {
method1(A a) {
a.foo();
}
}
I get as result compile errors of forward declaration and use of incomplete type.
But why is this happening? (I have declared class A before using it?)
The compiler hasn't seen the definition of A at the point where you call A::foo(). You can't call a method for an incomplete type - i.e. a type for which the compiler doesn't yet know the definition of. You need to define the calling method after the compiler can see the definition of class A.
class A;
class B
{
public:
void method1(A a);
};
class A
{
public:
void method1(B b) { }
void foo() { }
};
void B::method1(A a)
{
a.foo();
}
In practice, you may want to place the definition for B::method1() in a separate cpp file, which has an #include for the header file containing class A.
C++ INCLUDE Rule : Use forward declaration when possible.
B only uses references or pointers to A. Use forward declaration then : you don't need to include . This will in turn speed a little bit the compilation.
B derives from A or B explicitely (or implicitely) uses objects of class A. You then need to include
Source: http://www-subatech.in2p3.fr/~photons/subatech/soft/carnac/CPP-INC-1.shtml
For avoiding multiple inclusion of header files you should include a guard, to prevent the compiler from reading the definitions more that once:
#ifndef EMCQUEUE_HH
#define EMCQUEUE_HH
// rest of header file ...
// definition code here...
#endif
See Industrial Strength C++ Chapter Two: Organizing the code.

interfaces, inheritance, and what between them

if i want to have 3 classes, which have common fields (and i want them to be static)
and they have a common function (which needed to be overridden, i.e virtual)
what the best design to do this?
do i need to create an interface in a header file
and then create it's .cpp file and get the 3 classes inheritance from it?
what about the static members?
can i declare them in the header file?
when creating header file which representing interface, do i have to create it's .cpp file?
Declare the classes in header files.
This is so that the declaration can be shared between multiple source files (with #include) and thus obey the (One definition rule).
It is traditional (though not required) that each class has its own file. To make it consistent and easy to find things you should name the file after the class. So Class A should be declared in A.h and defined in A.cpp.
MyInterface.h
class MyInterface
{
protected:
static int X;
static int Y;
static int Z;
public:
// If a class contains virtual functions then you should declare a vritual destructor.
// The compiler will warn you if you don't BUT it will not require it.
virtual ~MyInterface() {} // Here I have declared and defined the destructor in
// at the same time. It is common to put very simplistic
// definitions in the header file. But for clarity more
// complex definitions go in the header file. C++ programers
// dislike the Java everything in one file thing because it
// becomes hard to see the interface without looking at the
// documentaiton. By keeping only the declarations in the
// header it is very easy to read the interface.
virtual int doSomthing(int value) = 0; // Pure virtual
// Must be overridden in derived
};
A.h
#include "MyInterface.h"
class A: public MyInterface
{
public:
virtual int doSomthing(int value);
};
B.h
#include "MyInterface.h"
class B: public MyInterface
{
public:
virtual int doSomthing(int value);
};
C.h
#include "MyInterface.h"
class C: public MyInterface
{
public:
virtual int doSomthing(int value);
};
Now you define the implementation in the source files:
MyInterface.cpp
#include "MyInterface.h"
// Static members need a definition in a source file.
// This is the one copy that will be accessed. The header file just had the declaration.
int MyInterface::X = 5;
int MyInterface::Y = 6;
int MyInterface::Z = 7;
A.cpp
#include "A.h"
// Define all the methods of A in this file.
int A::doSomthing(int value)
{
// STUFF
}
B.cpp
#include "B.h"
int B::doSomthing(int value)
{
// STUFF
}
C.cpp
#include "C.h"
int C::doSomthing(int value)
{
// STUFF
}
There is no explicit "interface" thing in the C++ language.
If you'd like to have an interface-like class, that's a class with pure virtual methods (that is a method w/o definition, e.g. virtual void printme() = 0;).
Static variables are bound to object files (internal linkage). If you define them in your header file and include that header file into several cpp files, you'll end up having several definitions of that static variable (in different object files)
Since static variables are either global or part of a class, they cannot be 'common'. They belong to one class and may be accessed by another one.
Same goes for methods. One class has a method, another one may call it. If it's a derived class, it may also override it (that is either hide it or implement a virtual method).
Now, if you have three classes that have the same structure, you may (or may not) like to inherit them from a base class for several reasons. One is to avoid copying code. Another one is the main reason, that you may want to treat objects from the derived classes all the same, let's say you have a vehicle that you can use, but the vehicle may be a car, a bike or a plane. You want to use a vehicle, but don't mind which vehicle it actually is, so you create
class Vehicle
{
public:
virtual void use() = 0;
};
class Car
: public Vehicle
{
public:
virtual void use();
};
void Car::use()
{
// drive the car
}
Than you can use a Car as vehicle, for example
Car myCar;
Vehicle& myVehicle = static_cast< Vehicle& >(myCar);
myVehicle.use(); // drive the car.
That all is fundamental C++ OOP, look it up in some book.