Can someone tell me what is the correct way to create a .hpp and .cpp that includes classes, subclasses and methods? Do I have to use export "C" firstClass* create_object { return new firstClass; }? (I am working in C++.) Should I have file.hpp or file.h?
#include <string>
//public ?? how can i have this?
class firstClass
{
public:
firstClass();
class secondClass
{
public:
secondClass();
std::string name;
virtual std::string method1();
} *sec;
virtual void DoSomething();
} *first;
// And for a private class?
class private *priv;
in file.cpp
#include file.hpp
firstClass::firstClass()
{
sec = new firstClass::secondClass();
}
std::string firstClass::secondClass::method1()
{
//code
}
And now if I have to extern an object for each class/subclass? It is necessary if I want to create an .so file and use dlsym and dlopen to access classes, subclasses and methods, modify values, send a reference to a specific method? Thanks!
extern "C" firstClass* create_object()
{return new firstClass}
extern "C" secondClass* create_object()
{return new secondClass}
Whether you have file.hpp or file.h is just a matter of preference. Personally, I use .hpp to indicate C++ rather than C.
In C++, unlike for example Java, classes in the global namespace are not public or private. You can, however, hide or limit access to classes in various ways. For example:
Having them private in another class.
Using namespaces.
A few other points:
The syntax for including file.hpp is #include "file.hpp"
Your firstClass and secondClass classes have virtual methods and a default destructor. You should make your destructor public and virtual, or protected and non-virtual
Classes are usually defined like this:
Class definition:
class SomeClass {
// code
};
and when you want a pointer to it, you write SomeClass* myPointer;, rather than the way you declare first and sec.
You usually want to put class declarations and/or definitions in header files, along with function declarations. Implementations goes in the source files. Example:
// Header file:
class FirstClass {
public:
FirstClass();
void DoSomething();
};
// Source file:
FirstClass::FirstClass()
{
// code
}
void FirstClass::DoSomething()
{
// code
}
I'd recommend you to pick up a C++ textbook, where such basics are plentifully covered. My personal recommendation is Accelerated C++.
Related
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.
I've designed and developed a SHARED library and would like to distribute it, but I don't want to expose the private methods and private attributes.
Here is what I have tried with no success:
Full header, used to build the library mylib.so:
namespace MYNAMESPACE{
enum class MyReturnCode {
Success = 1,
MyRetCode01,
MyRetCode02
};
class MyException {
public:
MyException(
MYNAMESPACE::MyReturnCode _code,
std::string _message);
MYNAMESPACE::MyReturnCode code;
std::string message;
};
class MyClass {
public:
MyClass();
~MyClass();
void initialize();
std::string function01();
std::string function02();
int attribute01;
float attribute02;
private:
std::string function03();
int attribute03;
float attribute04;
};
}
The header I designed to use when sharing mylib.so with others is similar to this one, but without the private section.
When I call the function initialize, the attributes attribute03 and attribute04 are correctly set and I can use them until some point.
THE ACTUAL PROBLEM WITH ALL THIS SCENARIO
I don't know why, but at some point, attribute03 and attribute04 just get some trash and I have a SIGABRT that ends the execution.
EDITED (2nd time)
After some comments, I went into the following PIMPL solution and now it is working fine.
header my_class_api.hpp, used to distribute with mylib.so
#include <memory>
namespace MY_API {
class MyClassAPI {
public:
virtual ~MyClassAPI() {};
virtual void initialize() = 0;
virtual std::string function01() = 0;
virtual std::string function02() = 0;
static std::shared_ptr<MyClassAPI> get_my_api();
};
}
NEW full header my_class.hpp, used to build the library mylib.so:
#include "my_class_api.hpp"
namespace MYNAMESPACE{
class MyClass : public MY_API::MyClassAPI {
public:
MyClass();
~MyClass() override;
void initialize() override;
std::string function01() override;
std::string function02() override;
private:
std::string function03();
int attribute03;
float attribute04;
};
}
Implementation file my_class.cpp
#include "my_class.hpp"
namespace MY_API {
std::shared_ptr<MyClassAPI> MyClassAPI::get_my_api() {
return std::make_shared<MYNAMESPACE::MyClass>();
}
}
namespace MYNAMESPACE {
MyClass::MyClass() { }
MyClass::~MyClass() { }
void MyClass::initialize() { }
std::string MyClass::function01() { }
std::string MyClass::function02() { }
}
Thanks everybody that helped me! I hope this example helps others too.
As mentioned above, PIMPL is the best solution for that. Qt, for example, uses PIMPL on all its classes to also ensure binary compatibility. That is, when a newer version of a DLL is installed, it is compatible with all old binaries, because the public interface does not change.
https://en.cppreference.com/w/cpp/language/pimpl
The header I designed to use when sharing mylib.so with others is similar to this one, but without the private section.
The header that you use to build the .so shared lib should be the same as the header that you expose to the client. One cannot have private members, and the other not have them. The client will not consider the private members to be part of the class, but when executing a function, it would try to use a memory that does not belong to the instance.
As mentioned, PIMPL is a commonly used solution. In your class's private section you can have a MyClassData* mData; declaration. In your .cpp file, you can define the struct MyClassData, and initiate its members. In the constructor, allocate memory to mData, and in the destructor delete the memory.
EG,
//this is myclass.h
class myclass
{
public:
int publicfunction();
private:
int myprivatefunction();
};
//myclass.cpp
#include "myclass.h"
int myclass::publicfunction()
{myprivatefunction();
blabla...}
int myclass::privatefunction()
{blabla...}
So, for users can access the class,we will provide the header file to the users. But shouldn't we conceal the internal implement details of the class??? I mean, when the users get myclass.h, they will find that the class contains a private function myprivatefunction
You can export the private members inside a struct
//this is myclass.h
class myclass{
private:
struct myClassPrivateMembers;
myClassPrivateMembers* privParts;
public:
// ...
};
And in the *.cpp file:
//this is myclass.cpp
struct *myClassPrivateMembers{
int myprivatefunction();
}
myclass::myclass(){
privParts = new myClassPrivateMembers;
};
That way the user won't be able to see things you hidden inside myClassPrivateMembers, because they'll be inside the *.cpp file, not declared in the header file.
This is widelly known as the "pimpl" idiom.
Your header file isn't just your public interface. It's a description of your data layout for the compiler. It is perfectly normal that the private members get shown in the header file. private is not a security mechanism and never will be.
It's a bit strange, but it falls out from a simple yet efficient way of going about the problem.
You might as well separate your interface and your implementation.
myinterface.h
class myinterface
{
public:
virtual int publicfunction() = 0;
};
myclass.h
class myclass : public myinterface
{
public:
virtual int publicfunction();
private:
int privatefunction();
};
myclass.cpp
#include "myclass.h"
int myclass::publicfunction()
{myprivatefunction();
blabla...}
int myclass::privatefunction()
{blabla...}
You don't have to expose myclass.{h,cpp} to library users.
But this might be an overkill... (I would call this "Java folks' way")
If I'm creating a static library with a header file such as this:
// Myfile.h
#include "SomeHeaderFile.h" // External library
Class MyClass
{
// My code
};
Within my own project I can tell the compiler (in my case, Visual Studio) where to look for SomeHeaderFile.h. However, I don't want my users to be concerned with this - they should be able to include my header without having to inform their compiler about the location of SomeHeaderFile.h.
How is this type of situation normally handled?
This is a classic "compilation firewall" scenario. There are two simple solutions to do:
Forward-declare any classes or functions that you need from the external library. And then include the external library's header file only within your cpp file (when you actually need to use the classes or functions that you forward-declared in your header).
Use the PImpl idiom (or Cheshire Cat) where you forward-declare an "implementation" class that you declare and define only privately (in the cpp file). You use that private class to put all the external-library-dependent code to avoid having any traces of it in your public class (the one declared in your header file).
Here is an example using the first option:
#ifndef MY_LIB_MY_HEADER_H
#define MY_LIB_MY_HEADER_H
class some_external_class; // forward-declare external dependency.
class my_class {
public:
// ...
void someFunction(some_external_class& aRef); // declare members using the forward-declared incomplete type.
};
#endif
// in the cpp file:
#include "my_header.h"
#include "some_external_header.h"
void my_class::someFunction(some_external_class& aRef) {
// here, you can use all that you want from some_external_class.
};
Here is an example of option 2:
#ifndef MY_LIB_MY_HEADER_H
#define MY_LIB_MY_HEADER_H
class my_class_impl; // forward-declare private "implementation" class.
class my_class {
private:
std::unique_ptr<my_class_impl> pimpl; // a vanishing facade...
public:
// ...
};
#endif
// in the cpp file:
#include "my_header.h"
#include "some_external_header.h"
class my_class_impl {
private:
some_external_class obj;
// ...
public:
// some functions ...
};
my_class::my_class() : pimpl(new my_class_impl()) { };
Say the external header file contains the following:
external.h
class foo
{
public:
foo();
};
And in your library you use foo:
myheader.h:
#include "external.h"
class bar
{
...
private:
foo* _x;
};
To get your code to compile, all you have to do is to forward declare the foo class (after that you can remove the include):
class foo;
class bar
{
...
private:
foo* _x;
};
You would then have to include external.h in your source file.
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.