How to call static class method from a struct? - c++

I've been always avoiding the following in C++ (which I believe is C++03 used in VS 2008) but now I'm curious if it's possible to do this? Let me explain it with the code.
//Definitions.h header file
//INFO: This header file is included before CMyClass definition because
// in contains struct definitions used in that class
struct MY_STRUCT{
void MyMethod()
{
//How can I call this static method?
int result = CMyClass::StaticMethod();
}
};
then:
//myclass.h header file
#include "Definitions.h"
class CMyClass
{
public:
static int StaticMethod();
private:
MY_STRUCT myStruct;
};
and:
//myclass.cpp implementation file
int CMyClass::StaticMethod()
{
//Do work
return 1;
}

In this case, you would need to move the implementation of MY_STRUCT::MyMethod outside the header file, and put it somewhere else. That way you can include Definitions.h without already having CMyClass declared.
So your Definitions.h would change to:
struct MY_STRUCT{
void MyMethod();
};
and then elsewhere:
void MY_STRUCT::MyMethod()
{
int result = CMyClass::StaticMethod();
}

Related

How to define a private member function only in cpp

So consider I have a class with a private member variable and a private function which I do not want to define in the header file, because I want to "hide" it from the user.
How can I make this? I can not access the private variable without the declaration of the function in the header.
So what works is something like this:
// header file
class Testclass {
public:
// ...
private:
const int m_i;
void func() const;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
But I want something like this:
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
Which possibilities do I have? I read something about the PIMPL Idiom, but I am not sure if this is what I want, since it looks a bit cumbersome coding-wise.
You can have non-member helper functions in the cpp file, that the class members can use. However, they would have to pass the private variable as a parameter.
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
void func(int m_i) {
int j = m_i; //private member variable supplied by caller
}
// ...
Normally one achieves this through the PIMPL (Pointer to IMPLementation) idiom. In your header file you have:
class MainClass
{
public:
void public_function();
private:
class Impl;
Impl* impl;
};
Note that the header file does not contain the definition of the Impl class, only its declaration.
You then define that class in your cpp file and forward the calls from your public interface to the functions of the impl class:
class MainClass::Impl
{
void actualfunc()
{
//do useful stuff here
}
};
void MainClass::public_function()
{
return impl->actualfunc();
}
Apart from your indended hiding of unwanted members from your class users, the PIMPL idiom provides the additional benefit that if no changes are made to the interface of the class, the users of the class need not be recompiled.

Good practice to call a static function inside class or struct

I wonder what is the better practice to call a static function(and variables) inside a class or struct between A and B.
A: ClassName::functionName();
B: functionName();
Here's my simple example code:
In header file,
typedef struct _mystruct
{
static void myfunction();
} t_mystruct;
And in CPP file,
void t_mystruct::myfunction()
{
//do something
}
Now, in the same CPP file, what is the better practice to call this static function between A and B?
A: t_mystruct::myfunction();
B: myfunction();
Calling straight myfunction(); is only feasible if you are inside t_mystruct's implementation. In which case you can do according to your preferred coding style:
// .h
struct t_mystruct // You can declare it directly that way
{
static void myfunction();
void myOtherFunction();
};
// .cpp
void t_mystruct::myOtherFunction()
{
myfunction(); // That's fine!
t_mystruct::myfunction(); // That's fine too!
}
Otherwise, you have to explicitely use its fully qualified name:
void anywhereElse()
{
t_mystruct::myfunction(); // Mandatory
myfunction(); // Does not compile
}
This is true for your whole codebase, not only for the considered .cpp file.

Better way of using an opaque pointer for Pimpl

I'm writing a C++ wrapper library around a number of different hardware libraries for embedded systems (firmware level), using various libraries from different vendors (C or C++). The API exposed by the header files should be vendor agnostic... all Vendor header libraries are not included in any of my header files.
A common pattern I have is making the vendor member data opaque, by only using a pointer to some "unknown" vendor struct/class/typedef/pod type.
// myclass.h
class MyClass
{
...
private:
VendorThing* vendorData;
};
and implementation (note: each implementation is vendor specific; all have the same *.h file)
// myclass_for_vendor_X.cpp
#include "vendor.h"
... {
vendorData->doSomething();
or
VendorAPICall(vendorData,...);
or whatever
The problem I have is that VendorThing can be lots of different things. It could be a class, struct, type or pod. I don't know, and I don't want to care in the header file. But if you pick the wrong one, then it doesn't compile if the vendor header file is included as well as my header file. For example, if this the actual declaration of VendorThing in "vendor.h":
typedef struct { int a; int b; } VendorThing;
Then you can't just forward-declare VendorThing as class VendorThing;. I don't care about what the type of VendorThing is at all, all I want is the public interface to think of it as void * (i.e allocate space for a pointer and that is it), and the implementation think of it using the correct pointer type.
Two solutions I have come across are the "d-pointer" method found in Qt, where you add a level of indirection by replacing VendorThing a new struct VendorThingWrapper
// myclass.h
struct VendorThingWrapper;
class MyClass
{
...
private:
VendorThingWrapper* vendorDataWrapper;
};
and in your cpp file
// myclass.cpp
#include "vendor.h"
struct VendorThingWrapper {
VendorThing* vendorData;
};
... {
vendorDataWrapper->vendorData->doSomething();
}
but this adds a second pointer dereference, which is not a huge deal, but as this is targeting embedded systems, I don't want to add that overhead just because the language can't do what I want.
The other thing is just declare it void
// myclass.h
class MyClass
{
...
private:
void* vendorDataUntyped;
};
and in the implememtation
//myclass.cpp
#include "vendor.h"
#define vendorData ((VendorThing*)vendorDataUntyped)
... {
vendorData->doSomething();
}
but #define's always leave a bad taste in my mouth. There must be something better.
You can avoid the additional pointer dereference by using:
#include "vendor.h"
struct VendorThingWrapper : public VendorThing {};
Of course, at that point, it makes more sense to use the name MyClassData instead of VendorThingWrapper.
MyClass.h:
struct MyClassData;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassData* myClassData;
};
MyClass.cpp:
struct MyClassData : public VendorThing {};
MyClass::MyClass() : myClassData(new MyClassData())
{
}
MyClass::~MyClass()
{
delete myClassData;
}
Update
I was able to compile and build the following program. The unnamed struct is not a problem.
struct MyClassData;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassData* myClassData;
};
typedef struct { int a; int b; } VendorThing;
struct MyClassData : public VendorThing
{
};
MyClass::MyClass() : myClassData(new MyClassData())
{
myClassData->a = 10;
myClassData->b = 20;
}
MyClass::~MyClass()
{
delete myClassData;
}
int main() {}
If you are willing to go the route of the VendorThingWrapper, then you simply allow the wrapper to contain the data itself, rather than a pointer to it. This gives you the abstraction layer and avoids the extra dereference.
// myclass.cpp
#include "vendor.h"
struct VendorThingWrapper {
VendorThing vendorData;
};
... {
vendorDataWrapper->vendorData.doSomething();
}

Can a struct member(function) be defined before struct itself?

I'm new to C++, and I have a question: Can a member of struct that's a function, be defined before the struct itself?
Like this:
void foo_t::SayHello() {
printf("Hello,World!\n");
}
struct foo_t {
void SayHello();
};
Because by using this I split struct in a foo.h and SayHello() function in a C file.
EDIT::
And then include the .c in the top of .h file. Not in end of file.
I'm sorry for don't be more specific because I new to C++ and I don't know about C++'s terms.
No. (Point)
But you might do:
class foo_t;
void say_hello(const foo_t& foo) // defined in a source
struct foo_t {
void SayHello() const { say_hello(*this); }
};
But: "And then include the .c in the top of .h file. Not in end of file." makes me shiver.
No, but you can make a function proxy:
void foo_t_SayHello() {
printf("Hello,World!\n");
}
struct foo_t {
void SayHello() { foo_t_SayHello(); }
};
A decent compiler will inline this, resulting in no overhead.

Is pimpl compatible with anonymous namespaces?

I am trying to use the pimpl pattern and define the implementation class in an anonymous namespace. Is this possible in C++? My failed attempt is described below.
Is it possible to fix this without moving the implementation into a namespace with a name (or the global one)?
class MyCalculatorImplementation;
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
MyCalculatorImplementation* pimpl;
};
namespace // If i omit the namespace, everything is OK
{
class MyCalculatorImplementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
}
// error C2872: 'MyCalculatorImplementation' : ambiguous symbol
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
int MyCalculator::CalculateStuff(int x)
{
return pimpl->Calculate(x);
}
No, the type must be at least declared before the pointer type can be used, and putting anonymous namespace in the header won't really work. But why would you want to do that, anyway? If you really really want to hide the implementation class, make it a private inner class, i.e.
// .hpp
struct Foo {
Foo();
// ...
private:
struct FooImpl;
boost::scoped_ptr<FooImpl> pimpl;
};
// .cpp
struct Foo::FooImpl {
FooImpl();
// ...
};
Foo::Foo() : pimpl(new FooImpl) { }
Yes. There is a work around for this. Declare the pointer in the header file as void*, then use a reinterpret cast inside your implementation file.
Note: Whether this is a desirable work-around is another question altogether. As is often said, I will leave that as an exercise for the reader.
See a sample implementation below:
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
void* pimpl;
};
namespace // If i omit the namespace, everything is OK
{
class MyCalculatorImplementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
}
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
MyCalaculator::~MyCalaculator()
{
// don't forget to cast back for destruction!
delete reinterpret_cast<MyCalculatorImplementation*>(pimpl);
}
int MyCalculator::CalculateStuff(int x)
{
return reinterpret_cast<MyCalculatorImplementation*>(pimpl)->Calculate(x);
}
No, you can't do that. You have to forward-declare the Pimpl class:
class MyCalculatorImplementation;
and that declares the class. If you then put the definition into the unnamed namespace, you are creating another class (anonymous namespace)::MyCalculatorImplementation, which has nothing to do with ::MyCalculatorImplementation.
If this was any other namespace NS, you could amend the forward-declaration to include the namespace:
namespace NS {
class MyCalculatorImplementation;
}
but the unnamed namespace, being as magic as it is, will resolve to something else when that header is included into other translation units (you'd be declaring a new class whenever you include that header into another translation unit).
But use of the anonymous namespace is not needed here: the class declaration may be public, but the definition, being in the implementation file, is only visible to code in the implementation file.
If you actually want a forward declared class name in your header file and the implementation in an anonymous namespace in the module file, then make the declared class an interface:
// header
class MyCalculatorInterface;
class MyCalculator{
...
MyCalculatorInterface* pimpl;
};
//module
class MyCalculatorInterface{
public:
virtual int Calculate(int) = 0;
};
int MyCalculator::CalculateStuff(int x)
{
return pimpl->Calculate(x);
}
namespace {
class MyCalculatorImplementation: public MyCalculatorInterface {
...
};
}
// Only the ctor needs to know about MyCalculatorImplementation
// in order to make a new one.
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
markshiz and quamrana provided the inspiration for the solution below.
class Implementation, is intended to be declared in a global header file and serves as a void* for any pimpl application in your code base. It is not in an anonymous/unnamed namespace, but since it only has a destructor the namespace pollution remains acceptably limited.
class MyCalculatorImplementation derives from class Implementation. Because pimpl is declared as std::unique_ptr<Implementation> there is no need to mention MyCalculatorImplementation in any header file. So now MyCalculatorImplementation can be implemented in an anonymous/unnamed namespace.
The gain is that all member definitions in MyCalculatorImplementation are in the anonymous/unnamed namespace. The price you have to pay, is that you must convert Implementation to MyCalculatorImplementation. For that purpose a conversion function toImpl() is provided.
I was doubting whether to use a dynamic_cast or a static_cast for the conversion. I guess the dynamic_cast is the typical prescribed solution; but static_cast will work here as well and is possibly a little more performant.
#include <memory>
class Implementation
{
public:
virtual ~Implementation() = 0;
};
inline Implementation::~Implementation() = default;
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
std::unique_ptr<Implementation> pimpl;
};
namespace // Anonymous
{
class MyCalculatorImplementation
: public Implementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
MyCalculatorImplementation& toImpl(Implementation& impl)
{
return dynamic_cast<MyCalculatorImplementation&>(impl);
}
}
// no error C2872 anymore
MyCalculator::MyCalculator() : pimpl(std::make_unique<MyCalculatorImplementation>() )
{
}
int MyCalculator::CalculateStuff(int x)
{
return toImpl(*pimpl).Calculate(x);
}