Invoke a base class constructor from the other module - c++

Let I've two .cpp files: a.cpp and b.cpp which contains classes defenition as the following:
//a.cpp
class A
{
public:
A(){ \\some actions }
}
//b.cpp
class A;
class B : A
{
public:
B():A(){ \\some actions }
}
But during the compile time I've an error. The error's description is:
ConcreteSubject.cpp:5:25: error: invalid use of incomplete type ‘class
Subject’ ConcreteSubject.cpp:3:7: error: forward declaration of ‘class
Subject’ ConcreteSubject.cpp: In constructor
‘ConcreteSubject::ConcreteSubject()’: ConcreteSubject.cpp:21:38:
error: type ‘Subject’ is not a direct base of ‘ConcreteSubject’
Is it possible to avoid #include "a.cpp"?

You should move class declaration of A to a header file and include that header file in you b.cpp file. If you don't do this, b.cpp compilation unit has no way to know the list of constructors implemented (explicitly or implicitly) by classs A.
Including a cpp file is not a good idea. You should not do this.
//a.h
class A
{
public:
A();
}
//a.cpp
A::A(){ \\some actions }
//b.cpp
#include "a.h"
class B : A
{
public:
B():A(){ \\some actions }
}

Related

std::set with derived class object but base class comparator with gcc8.1

a.h
#ifndef _A__
#define _A__
class A {
public:
struct Less {
bool operator() (const A* const &k1, const A* const &k2) const
{
return k1->_a < k2->_a;
}
};
A(int a) : _a(a)
{
;
}
virtual ~A()
{
;
}
private:
int _a;
};
#endif
b.h
#ifndef _B__
#define _B__
#include "a.h"
class B : public A {
public:
B(int a) : A(a)
{
;
}
~B()
{
;
}
};
#endif // _B__
c.cpp
#include <set>
#include "a.h"
class B;
class C
{
std::set<B*, A::Less> _set;
};
When c.cpp is compile with g++ 8.1, it fails to compile with this static check error
/export/dev6/rajpal/gcc/8.1.0/bin/g++ -c c.cpp
In file included from /export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/set:60,
from c.cpp:1:
/export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<B*, B*, std::_Identity<B*>, A::Less, std::allocator<B*> >':
/export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/bits/stl_set.h:133:17: required from 'class std::set<B*, A::Less>'
c.cpp:6:25: required from here
/export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/bits/stl_tree.h:452:21: error: static assertion failed: comparison object must be invocable with two arguments of key type
static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I understand error is because at compile time, compiler is not able to determine how to compare _Key=B* and if I make available definition of B, it should work just fine.
But, my question is if there is any way to tell compiler that B is actually derived from A and there is a way to compare A objects.
Also please note that I don't want to change std::set<B*, A::Less> to std::set<A*, A::Less> which should also fix this problem.
Well, this is actually a libstdc++ bug, and will be fixed in GCC 8.4:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85965
But, my question is if there is any way to tell compiler that B is actually derived from A
The only way to do that is to make the definition of B visible where you need that information.
There is nothing like forward declaration of classes to indicate that B is derived from A.

Having trouble to understand circular declaration

Hi i'm trying to create a factory method, that returns a derived class of class A, I'm having trouble understanding circular declaration, I hope you can help me solve this.
Thanks.
AChildOne.cpp
#include "AChildOne.h"
AChildOne.h
#ifndef ACHILDONE_H
#define ACHILDONE_H
#include "A.h"
class A_CHILD_ONE : public A {
};
#endif
A.cpp
#include "A.h"
void A::a(){
Factory::fact();
};
A.h
#ifndef A_H
#define A_H
#include "Factory.h"
class A {
public:
static void a();
};
#endif
Factory.cpp
#include "Factory.h"
A *Factory::fact(){
return new A_CHILD_ONE;
}
Factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "A.h"
#include "AChildOne.h"
class Factory {
public:
static A *fact();
};
#endif
Compilation error
g++ A.cpp Factory.cpp AChildOne.cpp -o test
In file included from Factory.h:5:0,
from A.h:4,
from A.cpp:1:
AChildOne.h:5:30: error: expected class-name before ‘{’ token
class A_CHILD_ONE : public A {
^
In file included from A.h:4:0,
from A.cpp:1:
Factory.h:9:10: error: ‘A’ does not name a type
static A *fact();
^
A.cpp: In static member function ‘static void A::a()’:
A.cpp:4:2: error: ‘fact’ is not a member of ‘Factory’
Factory::fact();
^
In file included from A.h:4:0,
from AChildOne.h:3,
from AChildOne.cpp:1:
Factory.h:9:10: error: ‘A’ does not name a type
static A *fact();
^
In Factory.h you try to include A.h; in A.h you try to include Factory.h.
Including Factory.h into A.cpp and removing from A.h should help.
Factory declaration depends on A interface. A declaration doesn't depend on Factory declaration but A definition does.
Also, Factory.h doesn't need to know about AChildOne.h but Factory.cpp does. So move #include AChildOne.h to Factory.cpp.

Why is linking successful when we placed definition of class in the header?

I've written the following code:
//--a.cpp--//
#include "base.h"
class B : public A
{
public:
void foo()
{
A::bar();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B *b= new B();
b->foo();
return 0;
}
//--b.cpp--//
#include "base.h"
void A::bar()
{
printf("class A");
}
//--base.h--//
class A
{
public:
void bar();
};
And it works. But I don't understand why it works correctly, but it doesn't work when we're put the class A definition into the a.cpp and b.cpp instead of base.h. I think that after preprocessing phase and before the compiling to object module the base.h just replaced to the content of base.h. And we have still redefinition of class A before the compilation phase.
Both a.cpp and b.cpp need access to the declaration of class A (which is what you have in base.h). I copied and pasted the contents of base.h (the declaration) at the top of a.cpp and b.cpp, and it compiled fine in Visual Studio 2012.
You do not want to put the definition of class A in both files. Classes can be declared in multiple places, but must be defined in only one.

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

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.