Forward Declaration for a Struct in C++ - c++

following is my header file
#ifndef _ASYNCHRONOUSCLASS_H
#define _ASYNCHRONOUSCLASS_H
#include "stdafx.h"
#include <windows.h>
typedef int (*functionCall)(void *);
typedef void * voidPtr;
class AsynchronousFunction{
//int returnVal;
//functionCall fCall;
//voidPtr param;
//HANDLE m_hEvent;
struct pImpl;
pImpl* m_pImpl;
public:
AsynchronousFunction(functionCall fCall, voidPtr param);
~AsynchronousFunction();
void functionExecuter();
int result();
protected:
private:
};
#endif
In the cpp file I want to implement the struct which contains following details.
*//int returnVal;*
*//functionCall fCall;*
*//voidPtr param;*
*//HANDLE m_hEvent;*
How can I implement this ? What would be suitable, forward declaration or pointer implementation ?

In a single translation unit you will need to provide the definition of the type. It will look like:
struct AsynchronousFunction::Impl {
// members and functions...
};
Note that I renamed pImpl into Impl, the p in the idiom is for pointer, the member in the containing class would be Impl* pImpl;.

Related

C++: struct forward declaration of anonymous struct causes "conflicting declaration"

I have got this hpp file:
struct rte_spinlock_t;
class A {
public:
void init();
private:
rte_spinlock_t* spinlock;
};
and the corresponding cpp file:
#include "A.hpp"
typedef struct {
int lock;
} rte_spinlock_t;
void A::init()
{
}
Now, compiling like this: g++ A.cpp I get this error:
A.cpp:5:3: error: conflicting declaration ‘typedef struct rte_spinlock_t rte_spinlock_t’
5 | } rte_spinlock_t;
| ^~~~~~~~~~~~~~
In file included from A.cpp:1:
A.hpp:2:8: note: previous declaration as ‘struct rte_spinlock_t’
2 | struct rte_spinlock_t;
| ^~~~~~~~~~~~~~
Obviously making the struct named it works, unfortunately I cannot control the typedef of struct rte_spinlock_t that is in a library.
How could I workaround this?
I expect to be able to forward an unnamed struct without getting into conflicting declaration.
From what I understand what you have is more-less this (erroneous code):
https://godbolt.org/z/zarsTq6oE
Why don't you use pimpl (private implementation) idiom for extra level of indirection and hiding the "gory details"?
Let's assume my X is your A, lib.h contains the troublesome typedef:
//example.cpp
#include "example.hpp"
#include "lib.h"
struct Impl
{
CStruct* cs;
};
void X::init()
{
clib_init(&impl->cs);
}
X::X()
{
impl = std::make_unique<Impl>();
}
X::~X() = default;
//example.hpp
#pragma once
#include <memory>
struct Impl;
struct X
{
X();
~X();
//rest of special functions omitted for brevity
//feel free to add them at your own leisure
void init();
std::unique_ptr<Impl> impl;
};
Live demo: https://godbolt.org/z/4jYGrYEjr
BTW, I made an assumption that your troublesome struct is C code based on some searching...

C++ Pimpl Idiom using a pre-existing class

We have a heavily-templated header-only codebase that a client would like access to. For example, let's say it contains the Foo class in the header foo.hpp:
#ifndef FOO_HEADER
#define FOO_HEADER
#include <iostream>
template <typename T>
struct Foo {
Foo(){
// Do a bunch of expensive initialization
}
void bar(T t){
std::cout << t;
}
// Members to initialize go here...
};
#endif /* FOO_HEADER */
Now we want to let the client try a reduced set of the functionality without exposing the core code and without rewriting the whole codebase.
One idea would be to use the PIMPL idiom to wrap this core code. Specifically, we could create a FooWrapper class with the header foo_wrapper.hpp:
#ifndef FOO_WRAPPER_HEADER
#define FOO_WRAPPER_HEADER
#include <memory>
struct FooWrapper {
FooWrapper();
~FooWrapper();
void bar(double t);
private:
struct Impl;
std::unique_ptr<Impl> impl;
};
#endif /* FOO_WRAPPER_HEADER */
and implementation foo_wrapper.cpp:
#include "foo.hpp"
#include "foo_wrapper.hpp"
struct FooWrapper::Impl {
Foo<double> genie;
};
void FooWrapper::bar(double t){
impl->genie.bar(t);
}
FooWrapper::FooWrapper() : impl(new Impl){
}
FooWrapper::~FooWrapper() = default;
This code works as I expect it: https://wandbox.org/permlink/gso7mbe0UEOOPG7j
However, there is one little nagging thing that is bothering me. Specifically, the implementation requires what feels like an additional level of indirection... We have to define the Impl class to hold a member of the Foo class. Because of this, all of the operations have this indirection of the form impl->genie.bar(t);.
It would be better if we could somehow tell the compiler, "Actually Impl IS the class Foo<double>", in which case, we could instead say impl->bar(t);.
Specifically, I am thinking something along the lines of typedef or using to get this to work. Something like
using FooWrapper::Impl = Foo<double>;
But this does not compile. So on to the questions:
Is there a nice way to get rid of this indirection?
Is there a better idiom I should be using?
I am targeting a C++11 solution, but C++14 may work as well. The important thing to remember is that the solution can't use the header foo.hpp in foo_wrapper.hpp. Somehow we have to compile that code into a library and distribute just the compiled library and the foo_wrapper header.
You can just forward-declare Foo in FooWrapper.h. This will allow you to declare a std::unique_ptr for it:
#ifndef FOO_WRAPPER_HEADER
#define FOO_WRAPPER_HEADER
#include <memory>
// Forward declaration
template <typename T>
class Foo;
struct FooWrapper {
FooWrapper();
~FooWrapper();
void bar(double t);
private:
std::unique_ptr<Foo<double>> impl;
};
#endif /* FOO_WRAPPER_HEADER */
foo_wrapper.cc:
#include "foo_wrapper.h"
#include "foo.h"
void FooWrapper::bar(double t) {
impl->bar(t);
}
FooWrapper::FooWrapper() : impl(std::make_unique<Foo<double>>()) {}
FooWrapper::~FooWrapper() = default;
Just use Foo<double>:
// forward declaration so that you don't need to include "Foo.hpp"
template class Foo<double>;
struct FooWrapper {
//...
std::unique_ptr<Foo<double>> impl;
};
// explicit template instantiation so that Foo<double> exists without distributing "Foo.hpp"
template class Foo<double>;
void FooWrapper::bar(double t){
impl->bar(t);
}

Error compiling header file with a map of type map<string,struct>

I'm having trouble compiling a class that has a map. I define, in the private, the struct and then I declare de map. The thing is that the compiler g++ gives me error in the functions where I use iterators to that map, since it seems that g++ doesn't recognise the struct.
.hh file:
#ifndef _X_HH_
#define _X_HH_
class X{
public:
(lots of function and procedure headers)
private:
struct something{
(Its attributes)
};
map<string,something> mymap;
};
#endif
#include <map>
#include <string>
class X{
public:
//
private:
struct something{
int a;
};
std::map<std::string,something> m_mymap;
};
int main(){
X xx;
}

invalid use of incomplete type error

This is simplified code just to show my question:
main.cpp
#include "one.hpp"
#include <iostream>
int main(){
One one;
std::cout << one.two->val;
}
one.hpp:
struct Two; <- forward declare Two
struct One{
One();
~One() { delete two;}
Two* two;
};
one.cpp
#include "one.hpp"
struct Two{
int val;
};
One::One(): two(new Two()) {}
When compiling this I get error invalid use of incomplete type 'struct Two'.
I assume that since Two is incomplete type I just cannot refer to its fields...
I am wondering is there any way to hide Two implementation in one cpp file and use it in another cpp file using this kind of forward declaration? Question comes from creating API where I would like to hide implementation on some classes.
You cannot delete an object of incomplete type.
The solution is to define the destructor in one.cpp, too.
one.hpp:
struct One {
~One();
// ...
};
one.cpp:
// ...
One::~One() { delete two; }
Wikipedia: "Opaque pointers are a way to hide the implementation details of an interface from ordinary clients, so that the implementation may be changed without the need to recompile the modules using it. ":
Header file released to clients:
struct opaque;
struct interface
{
~interface();
void test();
opaque* _p;
};
Header file not released to clients:
struct opaque
{
void test();
//...
};
interface implementation file:
#include "interface.h"
#include "opaque.h"
interface::~interface()
{
delete _p;
}
void interface::test()
{
_p->test();
}
// ...
opaque implementation file:
#include "opaque.h"
void opaque::test()
{
// actual implementation
}

How to call static class method from a struct?

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();
}