I got two classes separated in four files. The main class includes a sub class and needs to execute functions of it (not shown in the minimal example code). What I want to do is to execute a function of the main class in the scope of the subclass.
I think some ideas would be to inherit the functions in the sub class but I could not figure out how to do this.
MainClass.cpp
#include "MainClass.hpp"
void MainClass::mainCallback() {
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback() {
std::cout << "[subCallback] executed" << std::endl;
}
int main() {
MainClass mainClass;
mainClass.mainCallback();
SubClass subClass;
subClass.activateSubClass();
return 0;
}
MainClass.hpp
#pragma once
#include "SubClass.hpp"
#include <iostream>
class MainClass{
public:
void mainCallback();
void subCallback();
};
SubClass.cpp
#include "SubClass.hpp"
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
SubClass.hpp
#pragma once
class SubClass{
public:
void activateSubClass();
};
The error in SubClass.cpp is of course:
error: use of undeclared identifier 'mainClass'
Just subclass the subclass:
class SubClass: public MainClass {
public:
void activateSubClass();
};
This (public) way the SubClass makes all methods of MainClass callable in SubClass instances. You could also private inherit. That way only activateSubClass() 'ld be callable.
In activateSubClass you can call directly the methods of the parent class:
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
Don't forget to include MainClass.hpp in SubClass.hpp
You try to call a MainClass.subCallback() without having an instance of MainClass. According to me, this is the typical use case for static methods.
Then, I think you make your #include directives the wrong way. Indeed, MainClass does not seem to need to know SubClass but the opposite is true. I think it is better to include MainClass.hpp in SubClass.hpp. This will solve your circle dependencies problem.And you can write your main() function in another file.
EDIT: Example
MainClass.hpp:
#pragma once
class MainClass
{
public:
void mainCallback();
static void subCallback(); // mak it static to be able to call it without an instance of the class
};
MainClass.cpp:
#include "MainClass.hpp"
#include <iostream>
void MainClass::mainCallback()
{
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback()
{
std::cout << "[subCallback] executed" << std::endl;
}
SubClass.hpp:
#pragma once
class SubClass
{
public:
void activateSubClass();
};
SubClass.cpp:
#include "SubClass.hpp"
#include "MainClass.hpp" // MainClass inclusion
void Suclass::activateSubClass()
{
MainClass::subCallback(); // Call of the static method
}
main.cpp:
#include "MainClass.hpp"
#include "SubClass.hpp"
int main()
{
MainClass mc;
mc.mainCallback();
SubClass sc;
sc.activateSubClass(); // Will call MainClass::subCallback()
return 0;
}
I hope it can help you.
Related
The situation is like this:
//header file
#ifndef CLASSA_H
#define CLASSA_H
#include <stdint.h>
class ClassA
{
public:
void function1();
void function2();
};
#endif //CLASSA_H
//cpp file
#include "ClassA.h"
void ClassA::function1()
{
/* some code */
}
void ClassA::function2()
{
/* some more code */
}
void function3()
{
/* more code /*
}
//main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3();
}
I want to call function3() in main.cpp but without inheritance. I tried using the instance of ClassA but that says "function3 is not a member of classA".
Maybe I'm missing a concept, would be great if anyone can help.
When you try to call function3() with obj.function3() syntax, the compiler then tries to find if there's a function exists named function3 in the instance of the class (i.e. object).
Now, in this case, you can do two things:
Include void function3() in the public: of the class and change void function3() to void ClassA :: function3() to tell the compiler that the containing code is defined for the class member function.
Or, define the function inside the header file and prevent calling the function by defining the class object. It's obvious, isnce you can't access something which is declared outside of the class.
The code explanation of all the two above methods is as follows:
Method 1
ClassA.cpp
#include "ClassA.h"
...
void ClassA::function3() // definition of the class member function
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3(); // now it's inside the class member function
// hence, we may now use it
}
ClassA.h
...
class ClassA
{
public:
...
void function3(); // declared inside the class
};
#endif //CLASSA_H
Method 2
ClassA.h
...
void function3()
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
function3();
}
ClassA.cpp
class {
...
};
void function3()
{
/* more code */
}
But the second method will make the class useless, therefore, possibly you meant to achieve the first method and not the second.
i have the following problem:
I have two classes:
FooClass.h
#include <vector>
#include "BaseClass.h"
using namespace std;
class FooClass
{
public:
vector<BaseClass> vBaseClass;
void doStuff();
void addBaseClass(BaseClass &baseClass);
};
FooClass.cpp
#include <iostream>
#include "FooClass.h"
void FooClass::doStuff()
{
cout << "Well nice done" << endl;
}
void FooClass::addBaseClass(BaseClass &baseClass)
{
baseClass.updateData(this);
vBaseClass.push_back(baseClass);
}
And
BaseClass.h
#include "FooClass.h"
class BaseClass {
public:
void updateData(FooClass *pFooClass);
};
BaseClass.cpp
#include "BaseClass.h"
void BaseClass::updateData(FooClass *pFooClass)
{
//We try to get some data, and if we get the data we call pFooClass->doStuff
pFooClass->doStuff();
}
So, basically the function should be that i create one instance of FooClass.
Then i create multiple instances of BaseClass which i want to add to the vBaseClass vector in the FooClass.
If needet i want to access the BaseClass instance with vBaseClass[key] and call the doStuff() function in FooClass. I give FooClass as a pointer parameter because i want to have still access to the vBaseClass vector from the doStuff() function then which is called by an BaseClass instance.
Everything works fine, but when i add the vector i get the following errors:
error: ‘BaseClass’ was not declared in this scope
vector<BaseClass> vBaseClass;
error: template argument 1 is invalid
vector<BaseClass> vBaseClass;
error: template argument 2 is invalid
error: ‘BaseClass’ has not been declared
void addBaseClass(BaseClass &baseClass);
error: ‘FooClass’ has not been declared
void updateData(FooClass *pFooClass);
error: no matching function for call to ‘BaseClass::updateData(FooClass*)’
baseClass.updateData(this);
If someone knows the solution, many thanks!
Thanks to all, my issue is solved, here is the working code:
FooClass.h
#ifndef TESTPROJECT_FOOCLASS_H
#define TESTPROJECT_FOOCLASS_H
#include <vector>
#include "BaseClass.h"
using namespace std;
class BaseClass;
class FooClass
{
public:
vector<BaseClass> vBaseClass;
void doStuff();
void addBaseClass(BaseClass &baseClass);
};
#endif //TESTPROJECT_FOOCLASS_H
FooClass.cpp
#include <iostream>
#include "FooClass.h"
void FooClass::doStuff()
{
cout << "Well nice done" << endl;
}
void FooClass::addBaseClass(BaseClass &baseClass)
{
baseClass.updateData(this);
vBaseClass.push_back(baseClass);
}
BaseClass.h
#ifndef TESTPROJECT_BASECLASS_H
#define TESTPROJECT_BASECLASS_H
#include "FooClass.h"
class FooClass;
class BaseClass {
public:
void updateData(FooClass *pFooClass);
};
#endif //TESTPROJECT_BASECLASS_H
BaseClass.cpp
#include "BaseClass.h"
void BaseClass::updateData(FooClass *pFooClass)
{
//We try to get some data, and if we get the data we call pFooClass->doStuff
pFooClass->doStuff();
}
main.cpp // console output "Well nice done"
#include "lib/FooClass.h"
int main()
{
FooClass fooclass;
BaseClass baseclass;
fooclass.addBaseClass(baseclass);
}
Thanks to everyone, it is my first activity and question here and i am really impressed how fast i got answers, really thanks!
#
Because i got asked to say what the issue was and how i solved it, i addet
to FooClass.h
#ifndef TESTPROJECT_FOOCLASS_H
#define TESTPROJECT_FOOCLASS_H
class BaseClass;
and to BaseClass.h
#ifndef TESTPROJECT_BASECLASS_H
#define TESTPROJECT_BASECLASS_H
class FooClass;
So the main issue was that i had to declare BaseClass and FooClass as shown above in the header of each others class.
I'm having problems with my code with dynamic_cast. I have spent many hours trying to find a solution for this, but I still don't find the answer. I read that the problem could be because I didn't write forward declarations but I have already done that and still with the same problem.
Abstract class
#include "CRoute.h"
class CScreen
{
protected:
CRoute* m_pRoute;
public:
virtual ~CScreen();
virtual void connecToRoute(CRoute* route) = 0;
virtual void drawRoute() = 0;
};
Derived class
#include "CScreen.h"
class CGUIScreen : public CScreen
{
public:
void drawRoute();
void connecToRoute(CRoute* route);
};
Derived class
#include "CScreen.h"
class CCRTScreen : public CScreen
{
public:
void drawRoute();
void connecToRoute(CRoute* route);
};
Base Class
#include <string>
#include <iostream>
using namespace std;
class CScreen;
class CCRTScreen;
class CGUIScreen;
class CWaypoint
{
public:
CWaypoint();
void print(int format, CScreen* screenType);
};
Derived class
#include <iostream>
#include <string>
#include "CWaypoint.h"
using namespace std;
class CScreen;
class CCRTScreen;
class CGUIScreen;
class CPOI : public CWaypoint
{
public:
void print(int format, CScreen* screenType);
};
Method of CPOI
void CPOI::print(int format, CScreen* screenType)
{
if(dynamic_cast<CGUIScreen*>(screenType)) ---> Here is the error <<----
{
cout << "printing POI GUI " << endl;
}
else if(dynamic_cast<CCRTScreen*>(screenType)) ---> Here is the error <<----
{
cout << "printing POI CRT " << endl;
}
}
And the error I'm getting is the next one
..\myCode\CWaypoint.cpp:184:41: error: cannot dynamic_cast 'screenType' (of type 'struct CScreen*') to type 'struct CGUIScreen*' (target is not pointer or reference to complete type)
..\myCode\CWaypoint.cpp:184:44: error: expected unqualified-id before ')' token
..\myCode\CWaypoint.cpp:188:46: error: cannot dynamic_cast 'screenType' (of type 'struct CScreen*') to type 'struct CCRTScreen*' (target is not pointer or reference to complete type)
I read that the problem could be because I didn't write forward
declarations but I have already done that and still with the same
problem.
Quite the contrary; your forward declarations are what causes the errors.
A forward declaration, such as your class CScreen; line, simply tells the compiler: "There is a class called 'CScreen'. I'll give you more details later, but for now just keep in mind that this is a valid class name, OK?"
The compiler can then do very basic things with that class name; for example, it will accept pointer or reference declarations with it. That's why your print(int format, CScreen* screenType) line works. You don't need to know anything about CScreen other than its name to declare a pointer to it.
But how is the compiler supposed to accept a dynamic_cast with the class name? It does not really know anything about the class. In particular, it does not know that CGUIScreen or CCRTScreen are derived from CScreen. That's why at the point where you use dynamic_cast, the full class definitions are needed.
The header files for CWaypoint and CPOI (possible called waypoint.h and point.h?), can thus safely use forward declarations. As you correctly did:
waypoint.h:
class CScreen;
class CCRTScreen;
class CGUIScreen;
class CWaypoint
{
public:
CWaypoint();
void print(int format, CScreen* screenType);
};
point.h:
class CScreen;
class CCRTScreen; // not necessary but not invalid
class CGUIScreen; // not necessary but not invalid
class CPOI : public CWaypoint
{
public:
void print(int format, CScreen* screenType);
};
The implementation files, however, (possible called waypoint.cpp and point.cpp?), require the full definitions when you use a dynamic_cast:
point.cpp:
#include "point.h"
#include "screen.h"
#include "gui_screen.h"
#include "crt_screen.h"
#include <iostream>
using std::cout;
using std::endl;
void CPOI::print(int format, CScreen* screenType)
{
if(dynamic_cast<CGUIScreen*>(screenType))
{
cout << "printing POI GUI " << endl;
}
else if(dynamic_cast<CCRTScreen*>(screenType))
{
cout << "printing POI CRT " << endl;
}
}
By the way, it seems that CWaypoint should actually be an abstract base class, and that it possibly doesn't need an implementation file at all:
point.h:
class CScreen;
class CWaypoint
{
public:
virtual ~CWaypoint() {}
virtual void print(int format, CScreen* screenType) = 0;
};
P.S: If I may say so, I think your class names are confusing. A "Point" is definitely something more general than a "Waypoint", yet the inheritance relationship is exactly vice versa. Also, consider getting rid of Hungarian Notation. Just call your classes Screen instead of CScreen etc.
What the error message is telling you is that it does not know what the definition of CScreen or any of the derived classes are because you have forward declared them but not included their definitions.
Instead of
class CScreen;
class CCRTScreen;
class CGUIScreen;
Use
#include "CCRTScreen.h"
#include "CGUIScreen.h"
I'm noob in C++, and I have the following header file (Header.h)
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
using namespace std;
class Predicate
{
public:
virtual void print() = 0;
};
class UnaryIntegerPredicate : public Predicate
{
public:
virtual void print();
};
class BiaryIntegerPredicate : public Predicate
{
public:
virtual void print();
};
#endif
and in another separate .cpp file (Source.cpp), I tried to implement the print method, but got an "expected an expression" error.
#include "stdafx.h"
#include "Header.h"
#include <iostream>
using namespace std;
UnaryIntegerPredicate::UnaryIntegerPredicate() : Predicate()
{
virtual void print()
{
cout << "int : boolean" << endl;
}
}
what is wrong here, thanks!
I see you are probably coming from a Java background. What you need is
void UnaryIntegerPredicate::print()
{
cout << "int : boolean" << endl;
}
You don't need the stuff surrounding that. Since you have already declared in your header that UnaryIntegerPredicate derives from Predicate, you don't mention that again in the implementation file. You show that the print method that you are writing is the print method of the UnaryIntegerPredicate class by prefixing the name of the method with the name of the class as I have shown above.
You also don't need the virtual keyword in the cpp file because that is already specified in the header file.
I would like to create a basic abstract class in C++, where the subclasses are each in a separate file. My abstract class looks something like
class Process_Base{
public:
virtual void process() = 0;
}
Should a simple implementation like this be contained entirely in a header file? If it is do I need to have a .cpp file associated with it?
When I create the subclasses what should their header file look? I was thinking .cpp file for the subclass should look something like
#include "Process_Base.h"
class Hello_Process : public Process_Base{
void process(){
printf("%s\n", "Hello, World");
}
}
Could someone verify that I am approaching this correctly, and if not give a simple example of what I should be doing.
UPDATE
I continued with the implementation but I am now getting the following compiler error
g++ -c -Wall -g Process_Message.cpp
Process_Message.cpp:4: error: expected class-name before ‘{’ token
The following is the abstract class header
// Abstract header .hpp file
class Process_Base{
public:
virtual void process() = 0;
};
the subclass header
// The subclass header .hpp file
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
void process();
};
and the implementation
// Simple implementation .cpp file
#include <stdio.h>
#include <string.h>
class Process_Message : Process_Base {
public:
void process(){
printf("%s", "Hello");
}
}
I don't understand why I am getting the error, can someone please explain.
You're missing ; at the end of Process_Base declaration, when you include the file, the compiler goes nut. correct is:
class Process_Base{
public:
virtual void process() = 0;
};
Why this 'Process_Base' is there in below code? You have already mentioned inheritance in header file,right?
// Simple implementation .cpp file
#include <stdio.h>
#include <string.h>
class Process_Message : Process_Base {
public:
void process(){
printf("%s", "Hello");
}
}
Also don't forget to type ';' at the end of the class declaration after '}'
Your correct code should look like this:
//Process_Message.h
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
void process();
};
//Process_Message.cpp
#include <stdio.h>
#include <string.h>
#include "Process_Message.h"
void Process_Message::process()
{
printf("%s", "Hello");
}
Don't forget to declare your overrides as virtual, or they will hide parent methods instead of implementing them.
#include <iostream>
class Process_Base
{
public:
virtual ~Process_Base() {}
virtual void process() =0;
};
class Process_Message : public Process_Base
{
public:
virtual void process(); // <- virtual
};
void Process_Message::process()
{
std::cout << "Hello";
}
The above should compile fine