interfaces, inheritance, and what between them - c++

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.

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.

Difference between private static members and having them in the cpp file

Let's say I want class A to have a variable and a function that are available to all instances but only to them.
I have two ways of doing that (or are there more?):
Have them as private static members:
class A {
...
private:
static int myInt;
static void myMethod();
...
};
Simply have them in the cpp file:
// h file
class A {
...
};
// cpp file
static int myInt;
static void myFunction() { ... }
Both options will do just fine as I see it, but other than design related arguments, what are the differences?
Is any option better than the other?
Are there any performance or optimization issues?
Thanks.
Edit
Seems like I was not clear enough, so here's a better example (leaving the old one so that the previous comments/answers will make sense):
First option:
// h file
class A {
public:
A();
~A();
void doSomething();
private:
static std::queue queue;
static boost::mutex mutex;
static void initQueue();
};
// cpp file
// let's assume this method can be called multiple times but only initiates the queue on the first call
void A::initQueue() {
boost::unique_lock<boost::mutex> lock(A::mutex);
...
}
void A::A() {
A::initQueue();
}
void A::doSomething() {
// have full access to the A::queue/A::mutex
}
Second option:
// h file
class A {
public:
A();
~A();
void doSomething();
};
// cpp file
static std::queue queue;
static boost::mutex mutex;
static void initQueue() {
boost::unique_lock<boost::mutex> lock(Amutex);
...
}
void A::A() {
initQueue();
}
void A::doSomething() {
// have full access to the queue/mutex
}
As for the visibility, all I mean is that by including A.h I don't have access to the variables/functions, but only from within class A.
I don't mean how to guard them against malicious code or something.
Private members are an implementation detail which users of a class cannot access. Exposing them in header files creates unnecessary compilation dependencies. For example, private members may require including other header files which slow down compilation of translation units which include the header; changing an implementation detail in the header file requires recompiling all its users. Therefore, it is considered good practice to only expose in header files what users can directly use (the public API) and to avoid exposing implementation details in public API headers as much as possible.
Herb Sutter gives this subject a thorough treatment in GotW #100: Compilation Firewalls.
You can easily move all your non-public static class members into a .cc file and into an unnamed namespace.
Non-static data members can be moved into Pimpl or hidden behind an abstract interface. Pimpl advantage is that it does not require the user to deal with smart-pointers and factories directly and does not use virtual calls which can be slightly slower than non-virtual calls.
Run-time cost of hiding data members implementation is that the implementation of the member functions will have to be in the .cc so that the calls to your class API cannot be inlined without link-time code generation.
The difference is that the private static members are part of the class, and therefore have access to private and protected members of instances of the class. The free functions would not.
Example:
class A {
A(a) : _a(a) {}
private:
// legal - _a is accessible because get_a is part of A
static int get_a(const A& a) { return a._a; }
private:
int _a;
};
// illegal - _a is a private member of A
static get_a(const A& a) {
return a._a;
}
EDIT in response to OP's edit.
Both implementations are valid.

When exporting a class to a static lib in C++, how could I conceal the private function of the class?

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")

Hide contents of third-party C++ header file

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.

c++ .hpp and .cpp

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++.