Reputation: 614
I am writing a socket library in C++-17 which has a public class Socket
(i.e. I declare it in the .hpp
file). This class is supposed to be the interface between the user and the library.
I have a private type (declared in the .cpp
file) Packet
which is used to represent a packet in memory. The type Socket
has a few private helper methods which take Packet
as an argument.
If I try to only declare the helper method in the .cpp
file, the compiler complains that no such member exists. If I try to declare the method in the .hpp
then I cannot name the argument type as it is supposed to be private.
This is the public class declaration (in .hpp
):
class Socket {
private:
// ...private attributes
// void serialize(Packet p, uint8_t buffer[64]); // This is the helper function. `Packet` is private type
public:
// ...constructors and stuff
}
This is how I tried to define the function in the implementation file:
void Socket::serialize(Packet p, uint8_t buffer[64]) {
// ...a lot of things
}
How should I go about declaring such functions without making the library internals public.
Upvotes: 1
Views: 313
Reputation: 2774
This can be implemented using a forward declaration, which takes advantage of the fact that in C++ it is legal to use pointers and references to incomplete types.
Here's an example of how it would look in your situation.
// Public-facing include file
#include <cstdint>
class Packet; // forward declaration
class Socket {
private:
// ...private attributes
void serialize(const Packet & p, uint8_t buffer[64]); // This is the helper function. `Packet` is private type
public:
// ...constructors and stuff
};
#include "socket.hpp"
#include "packet.hpp"
void Socket::serialize(const Packet & p, uint8_t buffer[64]) {
*reinterpret_cast<int *>(buffer) = p.value; // note access of Packet member
}
// Private (i.e., library local) definition of Packet
class Packet {
public:
int value;
};
The file private/packet.hpp
is not shipped with the library. Thus, to includers of include/socket.hpp
, Packet
will be an opaque type.
Upvotes: 0
Reputation: 509
You could make Packet
a nested private class of Socket, meaning it wouldn't be exposed to the users of your library.
class Socket {
private:
class Packet {
...
};
public:
...
};
Upvotes: 1