Pass a C++ struct pointer from one class to another one - c++

I've two different classes (class1 class2) both of them have their own header and cpp files. Class2 has included the header of class1. Class1 has two structures which are public.
I want to call a method from class2 in class1 and to pass two pointers pointing on the structures.
The call of the method from class2 in class1. (obj is an object of class2 in class1):
obj.routine(ip_s.c_str(), &NLP_data_recv, &recv_data_data); //write to harddrive
Following the declaration of the method in class2:
int routine(std::string raw_data_re, struct NLP_data_header_package *Header_data, struct NLP_data_data_package *Data_data);
The following Error occurs:
“argument of type ""com::NLP_data_data_package *"" is incompatible with parameter of type ""NLP_data_data_package *""
How can I solve this problem? Thank you.
EDIT: Additional code:
class com header(class1):
#ifndef COM_H
#define COM_H
//...
#include "Dateiverwaltung.h"
//...
class com
{
private:
Dateiverwaltung obj;
//...
public:
int run(void);
com(std::array<std::string,TWO> socket);
~com();
struct NLP_data_header_package
{
//...
}NLP_data_recv;
struct NLP_data_data_package
{
//...
}recv_data_data;
class com cpp (class1)
//...
if (recv_command == DATA_COMMAND)
{
obj.routine(ip_s.c_str(), &NLP_data_recv, &recv_data_data); //write to harddrive
obj.ext_close_file();
}
//...
class Dateiverwaltung header(class2)
#ifndef DATEIVERWALTUNG_H
#define DATEIVERWALTUNG_H
//...
#include "communication.h"
//...
public:
Dateiverwaltung(char* directory_global_re);
~Dateiverwaltung();
int routine(std::string raw_data_re, struct NLP_data_header_package *Header_data, struct NLP_data_data_package *Data_data);
int ext_close_file(void);
//...
class Dateiverwaltung cpp (class2)
//...
int Dateiverwaltung::routine(string raw_data_re, struct NLP_data_header_package *Header_data, struct NLP_data_data_package *Data_data)
{
//...

The error says there's a "com::NLP_data_data_package"
and a "NLP_data_data_package"
That's two different classes (for the compiler), since they seem to be defined in different namespaces, namely com and the default namespace.

Related

Multiple accesses of a singleton object in many classes

I have a struct that multiple classes can access and edit. So I created this struct's object as static in class and created a get method.
In Class1.cpp:
#include "Class1.h"
static MyStruct struct;
MyStruct* Class1::get_my_struct()
{
return &struct;
}
I thought of creating this class`s object as a singleton to guarantee that this struct can be accessed through a single object.
In Class2.cpp:
#include "Class2.h" //Class1.h file included in this file.
void Class2::log_value()
{
Class1& singleton_obj_cls1 = Class1::getObject(): //return singleton object
singleton_obj_cls1 .get_my_struct().tempr_val=log_temp_val(); //log this value of struct by class 2 method
}
void Class2::change_value()
{
Class1& singleton_obj_cls1 = Class1::getObject():
//Do I have to get the singleton object for different methods even though they are in the same class?
//Can a singleton object get in one place in class and the whole class use it as a class member?
singleton_obj_cls1 .get_my_struct().tempr_val=45;
singleton_obj_cls1 .get_my_struct().x_val=66 ;
}
I have class 3 class that uses both class1 and class 2.By the way, I changed class2`constructor to a singleton.
In Class3.cpp:
#include "Class3.h" //Both Class1.h and Class2.h file included in this file.
void Class3::calculate_value()
{
Class1& singleton_obj_cls1 = Class1::getObject():
Class2& singleton_obj_cls2 = Class2::getObject():
singleton_obj_cls2.log_value();
singleton_obj_cls1.get_my_struct().pressure_value=300;
}
My third question is, Is there a better design method that you can fix instead of getting singleton objects in multiple places before using each struct or should I create the object once in the top class and give it as parameters to all 100 methods of perhaps 20 different classes that should have access to this struct?
Do I have to get the singleton object for different methods even though they are in the same class?
Can a singleton object get in one place in class and the whole class use it as a class member?
Use a member variable in your header file and initialize it in the constructor member initializer list:
Example Class2.h
#include "Class1.h"
class Class2 {
//...
private: // maybe public/protected to access from other classes
Class1& m_singleton_obj_cls1;
};
Example Class2.cpp
#include "Class2.h"
Class2::Class2()
: m_singleton_obj_cls1(Class1::getObject()) {
}
//...

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

C++ Can a class pass itself by reference?

Trying to pass a parent class object to a child class object so that the child class object has control over the parent class object's methods.
This is however resulting in header related issues.
I've tried forward declaring one of the classes but it seems whatever class is declared first always has trouble reading from the class declared below.
Both errors refer to Device' constructor where try to call dm's hello world method, they are:
Use of undefined type 'DeviceManager'
Left of '->HelloWorld' must point to class/struct/union/generic type
...
//main.cpp
#include "parent.h"
void main()
{
cout << "Created DeviceManager\n";
DeviceManager* deviceManager = 0;
deviceManager = new DeviceManager;
cout << "Giving DeviceManager a device\n";
deviceManager->p = new Device(deviceManager);
cout << "Giving Device a reference to DevicenManager\n";
deviceManager->Share();
}
...
class DeviceManager;
class Device
{
public:
Device(DeviceManager* manager)
{
dm = 0;
this->dm = manager;
this->dm->HelloWorld();
}
DeviceManager* dm;
};
//device manager
class DeviceManager
{
public:
DeviceManager()
{
p = 0;
}
void HelloWorld()
{
//if this calls we know the child has control over the parent.
cout << "Hello World";
}
Device* p;
};
Yes.
To solve circular dependencies with class member and function declarations, you can forward-declare a class:
class A;
class B {
A *a;
};
class A {
B *b;
};
To define class member functions that access members of the other class, you must define the function after the other class has been defined:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
Usually, in a C++ project, you wouldn't even encounter this problem: You would put function definitions, i.e. implementations, into .cpp files, while putting the class definitions into header files. Class forward declarations, if neccesary, could be put into their own header files that are included by all headers that need them.
A full example of how you would split the above code into multiple files:
a.cpp
#include "a.h"
#include "b.h"
void A::f(B &arg) {
arg.g(*this);
}
b.cpp
#include "b.h"
#include "a.h"
void B::g(A &arg) {
arg.f(*this);
}
a.h
#ifndef _A_H_
#define _A_H_
#include "forward_declarations.h"
class A {
public:
void f(B &arg);
};
#endif //_A_H_
b.h
#ifndef _B_H_
#define _B_H_
#include "forward_declarations.h"
class B {
public:
void g(A &arg);
};
#endif //_B_H_
forward_declarations.h
#ifndef _FORWARD_DECLARATIONS_H_
#define _FORWARD_DECLARATIONS_H_
class A;
class B;
#endif //_FORWARD_DECLARATIONS_H_
As a general rule of thumb, if you need to forward-declare a class, you might have misdesigned something and should think about whether there is a better way (but there also are perfectly valid use cases that require class forward declarations).
If you don't understand my #ifndef, #define and #endif preprocessor lines: These are header guards, and should be used with all files that are included somewhere else, exception you know precisely what you're doing. Believe me. You'll regret ommiting one.
If your problem is cyclic dependancy, like this:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
You can solve the problem be forward declaring one of the classes, and passing the object by pointer.
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};

C++ multiple file error

i have been attempting to pass an object into a function that belongs to a class both classes are in there own files...but when i try to pass the object as an argument for the function prototype it gives me an error saying that the object doesn't exist... ill provide some pseudo code to demonstrate my problem
//class 1 .h
class Class1
{
public:
void function(Class2);//this is were one of my errors
};
//class 1 .cpp
void Class1::function(Class2 object )//another error
{
//stuff happens
}
//main.cpp
//then i simply call these functions like this
Class1 object;
Class2 object2;
int main()
{
object.function1(object2);
return 0;
}
and i get errors "Class2' has not been declared"
and errors about Class1 prototype does not match any classes....
if someone could explain what im doing wrong it would be a great help also if more code is needed just ask and i will post it.
EDIT
when i was attempting to include class2`s header in class one i was using the wrong director as i forgot i had separated .h files into there own folder anyway now i have fixed that it all work thanks a lot everybody.
You'll need to include Class2's header file in Class1.h. That is:
//////////////////
//Class1.h
#include "Class2.h"
class Class1
{
public:
void function(Class2 arg);
};
If you are only using a pointer to Class2 as an argument, then you can forward declare Class2 instead of including the header, that is:
//////////////////
//Class1.h
//Forward declare Class2 so the compiler knows the name exists
class Class2;
class Class1
{
public:
void function(Class2 *arg);
};
There's some more info here if you're interested.
Well, in fact Class2 has not been declared!
So,
// Class2.h:
class Class2
{
};
// Class1.h:
#include "Class2.h"
class Class1
{
public:
void function(Class2 object);
};
// Class1.cpp:
#include "Class1.h"
void Class1::function(Class2 object)
{
//stuff happens
}
// main.cpp:
#include "Class1.h"
Class1 object;
Class2 object2;
int main()
{
object.function1(object2);
return 0;
}
Have you tried doing this yet?
main.cpp:
#include "class1.h"
...
int main()
{
Class1 object;
Class2 object2;
object.function1(object2);
return 0;
}
The trick is to use the #include "class1.h" at the top of your main.cpp file
Actually you need to make the compiler aware of the classes that u are going to use in the file anywhere.
Have a look at a very similar Question : http://www.gamedev.net/topic/553424-c-calling-member-of-another-class-in-another-file/

Two classes and inline functions

I have two classes and both of them uses some of the other class, on example:
// class1.h
class Class1;
#include "class2.h"
class Class1 {
public:
static Class2 *C2;
...
};
// class2.h
class Class2;
#include "class1.h"
class Class2 {
public:
static Class1 *C1;
...
};
And when I define it like in example above, it works (I also have some #ifndef to avoid infinite header recurency). But I also want to add some inline functions to my classes. And I read here that I should put definition of inline function in header file, because it won't work if I'll put them in cpp file and want to call them from other cpp file (when I do it I get undefined reference during linking). But the problem here is with something like this:
// class1.h
...
inline void Class1::Foo() {
C2->Bar();
}
I get error: invalid use of incomplete type ‘struct Class2’.
So how can I do it?
You need to delay including the header, but then include it and define your inline methods. By doing this in each header, they are self-sufficient and including one will always include the other, with include guards preventing infinite recursion.
A.hpp
#ifndef INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
#define INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
struct B;
struct A {
B* p;
void foo();
};
#include "B.hpp"
inline
void A::foo() {
if (p) p->bar();
}
#endif
B.hpp
#ifndef INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
#define INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
struct A;
struct B {
A* p;
void bar();
};
#include "A.hpp"
inline
void B::bar() {
if (p) p->foo();
}
#endif
You have it mix'd up. What you want is:
// class1.h
class Class2;
class Class1 {
public:
static Class2 *C2;
...
};
// class2.h
class Class1;
class Class2 {
public:
static Class1 *C1;
...
};
And include the respective headers in the source. The line:
class Class1; // or Class2
Declares an incomplete type, and you can have pointers and references to incomplete types. Upon usage, though, it needs to be complete. So just say "hey it'll exist!" in the header, and in the source tell it what it is.
My suggestion is that you place common methods and members into a base class, then derive C1 and C2 from the base class. This may fix the circular dependency issue.