Access to class which is only in cpp file of parent - c++

I want to call a class which is only in the file of a parent source class file. In fact I have 3 classes in 4 files:
parent.h
parent.cpp
child.h
child.cpp
The "main" classes are Child and Parent. The class Otherclass is in the parent.h file above the definition of the Parent class.
How can I get access to the class Otherclass which is only in the parent.cpp file in the child.cpp file?
(Unfortunately I'm not allowed to make big changes in the parent files.)
parent.cpp:
using ParentNamespace::Parent;
namespace other
{
class Otherclass
{
public:
Otherclass()
{
// do something
}
~Otherclass()
{
}
};
}
Parent::Parent()...
...
// here the Parent class continues normal
child.cpp:
#include "parent.h"
Child::Child() :
ParentNamespace::Parent()
...
...
...
// here I want to use Otherclass

How can I get acess to the class 'Otherclass' which is only in the parent.cpp file in the child.cpp file?
You can't. This is the entire purpose of header files. Use them.
(Unfortunately i'm not allowed to make big changes in the parent files.)
Either the existing code is completely broken and you should use this fact to become allowed…
…or these are internal classes that you shouldn't be trying to use in this way.

You can always create a separate header file for OtherClass, copy the OtherClass definition (all the code you would usually out into the header, not the code of non-inlined functions) there and #include this header into child.h. It is not very bad to have several definitions of the same class as long as you are absolutely sure that they will be identical. It is not also a right way to do, but if you can not move the OtherClass definition to (some) header file, then you can copy it to a new header.
Although of course the first question to ask is why at all the existing code is done this way. Maybe OtherClass is just an implementation detail of Parent that may change in future development and which you are not supposed to use.
An example code (not exactly for your case, but illustrates how you can work without any header files at all):
// a.cpp
#include <iostream>
class A{
public:
int x;
A(int);
};
class B {
public:
int y;
B(int);
};
A::A(int v) {
std::cout << "A::A " << v << std::endl;
}
// b.cpp
#include <iostream>
class A{
public:
int x;
A(int);
};
class B {
public:
int y;
B(int);
};
B::B(int v) {
std::cout << "B::B " << v << std::endl;
A a(v+10);
}
// main.cpp
class A{
public:
int x;
A(int);
};
class B {
public:
int y;
B(int);
};
int main() {
A a(10);
B b(20);
}
builds and works as expected. However, it would be really difficult to maintain all the definitions identical, so that's what headers are for.

Related

Class method friend of another class in two separate files

My goal is simple - I want to access the protected members of one class from the methods of another class. For this I have the following -
A.HPP
#ifndef A_HPP
#define A_HPP
#include "B.hpp"
using namespace std;
class A
{
protected:
int a;
public:
A();
~A(){};
friend void B::geta(A& ao);
};
inline A::A()
{
a = 2;
cout << a;
}
#endif
B.HPP
#ifndef B_HPP
#define B_HPP
using namespace std;
class A;
class B
{
protected:
int b;
public:
B();
~B(){};
void geta(A& ao);
};
inline B::B()
{
b = 1;
cout << b;
}
inline void B::geta(A& ao)
{
b = ao.a;
cout << b;
}
#endif
MAIN.CPP
#include <iostream>
#include "A.hpp"
#include "B.hpp"
int main()
{
A ao;
B bo;
bo.geta(ao);
return 0;
}
When I compile this I get the following error.
How do I fix this? Most answers that I see here are just putting all classes in one file and defining functions in appropriate positions to achieve this but I need them in separate files.
Option 1: Not inline
You can of course move the definition of B::geta to a B.cpp file which includes A.hpp and remove the inline keyword. But this might make compiler optimizations less likely.
Option 2: Weird #include logic
Your definitions as they are can only compile if the compiler sees a forward declaration of A, the definition of B, the definition of A, and the definition of B::geta, all in that order. So if you want the definition of A in one file and the definition of B in another, you'll need to get the preprocessor to do some switching back and forth between files.
A.hpp
// NO A_HPP include guard!
#ifdef INCLUDED_FROM_B_HPP
class A
{
protected:
int a;
public:
A();
~A(){};
friend void B::geta(A& ao);
};
inline A::A()
{
a = 2;
cout << a;
}
#else
# include "B.hpp"
#endif
B.hpp
#ifndef B_HPP
#define B_HPP
class A;
class B
{
protected:
int b;
public:
B();
~B(){};
void geta(A& ao);
};
#define INCLUDED_FROM_B_HPP
#include "A.hpp"
#undef INCLUDED_FROM_B_HPP
inline B::B()
{
b = 1;
cout << b;
}
inline void B::geta(A& ao)
{
b = ao.a;
cout << b;
}
#endif
So now if a file does #include "B.hpp", the preprocessor will:
Output the class A; and definition of B from the first part of B.hpp.
Define INCLUDED_FROM_B_HPP.
Output the definitions in A.hpp.
Clear the definition of INCLUDED_FROM_B_HPP.
Output the definitions of inline members of B from the second part of B.hpp.
If a file does #include "A.hpp" first, things are a bit trickier:
Since INCLUDED_FROM_B_HPP is not set, just immediately go into B.hpp.
Output the class A; and definition of B from the first part of B.hpp.
Define INCLUDED_FROM_B_HPP.
When the #include "A.hpp" in the middle of B.hpp is encountered, the preprocessor will go recursively back into A.hpp. But this time since INCLUDED_FROM_B_HPP is defined, it outputs the code contents of A.hpp.
Clear the definition of INCLUDED_FROM_B_HPP.
Output the definitions of inline members of B from the second part of B.hpp.
Option 3: friend class B;
Instead of specifying just the one member function B::geta to friend, just befriend the class itself, with the declaration friend class B;. Now A.hpp doesn't need to include B.hpp, so there's no circular dependency issue.
This doesn't much decrease encapsulation from the point of view of what access is and isn't possible, since normally any programmer who can modify any part of class B can also modify B::geta. But it does open possibilities of "accidentally" using non-public members of A in other members of B.
Option 4: Refactor access method
A.hpp
#ifndef A_HPP
#define A_HPP
class B;
class A
{
protected:
int a;
public:
A();
~A(){};
class AccessForB {
private:
static int geta(A& aobj) { return aobj.a; }
friend class ::B;
};
};
inline A::A()
{
a = 2;
cout << a;
}
#endif
B.hpp
...
inline void B::geta(A& ao)
{
b = A::AccessForB::geta(ao);
cout << b;
}
This code introduces a new sort of encapsulation: now class B can only get the value from member a, can't modify that value, and can't access any other non-public members of A. Additional accessors could be added for other members as appropriate. To permit modifying a member, the class could either provide "set" accessors, or an accessor that returns a reference. For non-public functions, the class could provide wrapper functions that just pass through to the actual function.
It's still true that it's possible for members of B other than B::geta to exploit the friendship, but now typing out A::AccessForB:: can't really be considered an accident.
... but I need them in separate files.
Move the inlined functions out to a separate B.cpp file that #include's A.hpp.
As being just seen as a forwarded class declaration A's declaration isn't yet complete at the point you're starting to use it in B.hpp, and the compiler complains about that righteously.
You can still retain the inline keyword, the compiler will respect it as a hint as usual.
Here's the sketch:
B.hpp
#ifndef B_HPP
#define B_HPP
using namespace std;
class A;
class B
{
protected:
int b;
public:
B();
~B(){};
void geta(A& ao);
};
#endif
B.cpp
#include "B.hpp"
#include "A.hpp"
inline B::B()
{
b = 1;
cout << b;
}
inline void B::geta(A& ao)
{
b = ao.a; // <<<<<<<<<<<< here's the problem to be solved
cout << b;
}
These questions and answers are very much related to your problem:
Resolve build errors due to circular dependency amongst classes
Why are C++ inline functions in the header?
C++ inline member function in .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();
}

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

Using global instance of a class by another global variable in other file

I have these files (simplified version)
a.h
class A
{
public:
A(int){}
int operator [](int a){return a;}
};
A a(2);
main.cpp
#include<a.h>
class B
{
public:
B(int){}
};
B b(a[2]);
int main()
{
//use b here...
}
Q: Can I use the above code ? Is it correct ?!
The code above (almost) compiles, but it probably doesn't do what you'd expect. A couple issues . . .
#include<a.h> should probably be #include "a.h" if a.h is located in the same directory as main.cpp.
B b(a[2]) might create a new instance of class A, instead of using the one you defined in a.h. Add extern A a; before you use a to tell your compiler that you want to use the a declared in another file.
Finally, depending on your application sometimes global variables can be frowned upon. If it's appropriate, consider using encapsulation instead of global variables. Something like
Class B {
public:
B(int i){}
private:
A a(); // Or extern A a;
};
Would work if you only needed to access a from b.

Header files and multiple class usage (EDIT: forward declarations)

I have a problem where I have several header files, and I need to include each of them in each other. Obviously, this cannot be done, because when I compile, the error "include nested too deeply" is thrown - as this essentially asks the compiler to enter an infinite include loop.
I could fix it using void pointers, but this seems like bad coding practice to me.
Here is an example of what I am trying to do, to aid understanding:
File-A:
#include "File-B"
#include "File-C"
class A
{
public: B* p_B;
public: C* p_C;
};
File-B:
#include "File-A"
#include "File-C"
class B
{
public: A* p_A;
public: C* p_C;
};
File-C:
#include "File-B"
class C
{
public: B* p_B;
};
This just shows where each class declaration is needed. Surely there is a better solution to void*.
EDIT: I am already using include guards, this code is just to help you see what I am trying to do.
You should use include guards:
#ifndef _FILE_A_H_
#define _FILE_A_H_
// Contents of FileA.h...
#endif
Possibly, also use forward declarations to break cyclic dependencies between the definitions of your data structures.
In FileA.h:
class B; // No need to #include "FileB.h"
class A
{
public:
B* pB;
};
In FileB.h:
class A; // No need to #include "FileA.h"
class B
{
public:
A* pA;
};
If you are using pointers or references to the other classes, and no code in the header file, you can use forward declarations:
class A; // Forward declaration
class C; // Forward declaration
class B
{
public:
A* p_A;
C* p_C;
};
If code in the header file refers to any members of the other classes, you will have to include the entire definitions of the other classes.
I would use include guards, which only include a certain file once.
#ifndef FILE_A
#define FILE_A
class A
{
public: B* p_B;
public: C* p_C;
};
#endif
http://en.wikipedia.org/wiki/Include_guard
It only includes the header file once per file.
You can also use #pragma_once, although it is not standard.
In the case that doesn't work, you can use a forward declaration.
class B;
class C;
class A
{
public: B* p_B;
public: C* p_C;
};
This is why you have #include <> guards.
#ifndef _FILE_B
#define _FILE_B
#include "File-A"
#include "File-C"
class B
{
public: A* p_A;
public: C* p_C;
};
#endif