I have a question in regards to building a project in C++ with abstract classes.
Suppose you have an abstract class A in a header file and then you have class B in a cpp file to create an object from class A. So far we have:
Class_A.h, Class_B.cpp
Within the Class_B.cpp file, I have included the header Class_A.h.
I want to now create objects of Class_B in a main file, for example: main.cpp. I added the header Class_A.h in main.cpp and when compiled, I get 'Class_B’ was not declared in this scope as an error. All files are in the same directory. I'm not too sure how to fix this or whether or not I am not using abstract classes correctly. All the examples I found online did something along the lines of: defining Class_B inside main.cpp without creating a separate cpp file for Class_B.
Example:
Abstract class: Car.h
Instance of abstract class: Toyota.cpp
main.cpp:
#include 'Car.h'
...
Toyota new_car = new Toyota(...);
Just need to organize your code. There's no hard and fast rules about how that needs to be done, but generally you define classes in header files (.h or .hpp) and implement the class in source files (.cpp). In this situation I would:
Class_A.h
class Class_A
{
public:
virtual void myFunc() = 0; // Class_A is abstract
...
}
Class_B.h
#include "Class_A.h"
class Class_B : public Class_A
{
public:
void myFunc();
...
}
Class_B.cpp
Class_B::myFunc()
{
...
}
main.cpp
#include "Class_B.h"
int main()
{
Class_B myClassB;
myClassB.myFunc();
...
return 0;
}
And of course you need to feed all the source files to your compiler correctly, at least Class_B.cpp and main.cpp in this case.
Related
I'm using wxWidgets with CodeBlocks, and I'm trying to instantiate a class called FileManager as an attribute of the Frame for wxWidgets, and pass the wxFrame parent to the constructor of FileManager. The objective is to be able to able to refer to the wxFrame from within FileManager. I'm getting an error "FileManager does not name a type". Not sure what I'm doing wrong thanks
The project is called "MullSimple_CB" so the main frame class is "Mull_Simple_CBFrame" Here are the files.
So the main object is a wxFrame object of class MullSimple_CBFrame, defined inside MullSimple_CBMain. The class I want instantiated as a member of that class is FileManager
MullSimple_CBMain.h
#ifndef MULLSIMPLE_CBMAIN_H
#define MULLSIMPLE_CBMAIN_H
#include "non-wx/file_manager.h"
class MullSimple_CBFrame: public wxFrame
{
public:
MullSimple_CBFrame(wxWindow* parent,wxWindowID id = -1);
virtual ~MullSimple_CBFrame();
// ERROR ON THIS LINE:
// "'FileManager' does not name a type"
FileManager fileManager(MullSimple_CBFrame parentFrame);
private
DECLARE_EVENT_TABLE()
};
#endif // MULLSIMPLE_CBMAIN_H
MullSimple_CBMain.cpp
#include "wx_pch.h"
#include "MullSimple_CBMain.h"
#include <wx/msgdlg.h>
#include "non-wx/file_manager.h"
MullSimple_CBFrame::MullSimple_CBFrame(wxWindow* parent,wxWindowID id)
{
FileManager fileManager(this);
}
FileManager.h
#ifndef FILE_MANAGER_H_INCLUDED
#define FILE_MANAGER_H_INCLUDED
#include "../MullSimple_CBMain.h"
class FileManager
{
private:
MullSimple_CBFrame storeMainFrame;
public:
// constructor
FileManager(MullSimple_CBFrame mainFrame);
};
#endif // FILE_MANAGER_H_INCLUDED
FileManager.cpp
#include "file_manager.h"
#include "../MullSimple_CBMain.h"
FileManager::FileManager(MullSimple_CBFrame mainFrame): storeMainFrame(mainFrame))
{
}
Your file_manager.h file includes MullSimple_CBMain.h and the MullSimple_CBMain.h file includes your file_manager.h.
You end up with a never ending chain of includes... which never resolve.
Consider putting forward declarations into a single .h file and then have your .h files only include it as opposed to including the individual class.h files themselves. The only time you need to include the class.h files themselves is if you need the compiler to know about the full definition of the class as opposed to just knowing the class exists at all.
Currently, I'm writing a project for fun and faced next problem.Let's suppose I'm creating class Bank and I want to define classes LoginController and Departure
class Bank{
class LoginController{
//some implemantation
}
class Departure{
//some departure
}
}
To avoid making huge declaration of Bank inside Bank.h I want to define them in separate files
//Bank.h
#include "LoginController.h"
#include "Departure"
class Bank{
class LoginController;
class Departure;
LoginController controller;
Departure departure;
...
}
//LoginController.h
class Bank; //forward declaration
class Bank::LoginController{
bool getAccess(Bank::Departure);
}
//Departure.h
//Departure depends on Bank class aswell
class Bank; //forward declartion
class Bank::Departure{...}
This code wont compile with huge stack trace.It can be solved with one big Bank.cpp and writing it all there, however, i don't want to make one huge file.
I assume this is a bad design problem, however, i'm still interested if it possible to implement this class as I wanted.Even if I define LoginController && Departure structure inside Bank i want separate cpp files for each class, however, header guard will close access to it after including it to one of cpp files.The best solution i can see is defining all in one header but not inside each other.
And one more question.Is it possible to define 1 header file with all includes like
#ifndef HeaderFile
#define HeaderFile
#include <iostream>
#include <memory>
....
#endif
From the previous question, i understand that this will open only for one file, therefore do we need to provide each file with needed headers. Including the same header to different files seems expensive.
You can put the #include directives inside the Bank class.
Bank.h
class Bank {
#include "LoginController.h"
#include "Departure.h"
// Bank implementation
}
LoginController.h
class LoginController {
// some implementation
}
Departure.h
class Departure {
// some implementation
}
In below code while compiling i am getting error ,
Error :
main.cpp:8:57: error: expected type-specifier before ‘Staircase’
std::unique_ptr algodiagnostic (new Staircase());
compilation command
g++ HardwareDiagnostic.cpp HardwareDiagnostic.h main.cpp -std=c++0x -o res
it works fine if compile entire code in single file without creating header file and main.cpp separately. Can anybody suggest how to fix this issue.
//HardwareDiagnostic.h//
#ifndef HARDWAREDIAGNOSTIC_H_
#define HARDWAREDIAGNOSTIC_H_
#include <iostream>
#include <memory>
using namespace std;
class HardwareDiagnostic
{
public:
virtual bool checkPort();
virtual void startDiagnostic();
virtual int publishAlgoDiagnosticInfo();
virtual void clearErrorStatus(){cout<<"Algorithm Diagnostics"<<endl;}
virtual ~HardwareDiagnostic() {cout<<"calling virtual destructor"<<endl;}
};
#endif /* HARDWAREDIAGNOSTIC_H_ */
//HardwareDiagnostic.cpp//
#include"HardwareDiagnostic.h"
class Localization : public HardwareDiagnostic
{
public:
Localization() { cout << "calling Localization constructor";}
bool checkPort(){cout<<"checkport :Localization";}
void startDiagnostic(){cout<<"start Diagnostic:Localization";}
int publishAlgoDiagnosticInfo() {cout<<"publish Diagnostic:Localization";}
void clearErrorStatus(){ cout<<"Localization:publish Diagnostic";}
~Localization () { cout<<"calling Localization destructor ";}
};
class Staircase : public HardwareDiagnostic
{
public:
Staircase () {cout<<"Staircase constructor";}
bool checkPort(){cout<<"Staircase";}
void startDiagnostic(){cout<<"StairCase:start Diagnostic";}
int publishAlgoDiagnosticInfo() {cout<<"StairCase:publish Diagnostic";}
void clearErrorStatus(){ cout<<"staircase:publish Diagnostic";}
~Staircase(){cout<<"calling Staircase destructor";}
};
//main.cpp//
#include "HardwareDiagnostic.h"
using namespace std;
int main() {
std::unique_ptr<HardwareDiagnostic> algodiagnostic (new Staircase());
return 0;
}
When compiler works on main.cpp, it sees Staricase usage, but doesn't see declaration for Staircase class, so error is raised. Your main.cpp file includes header, which describes HardwareDiagnostic class only, but no info for Staircase is provided.
Good practice is to keep class declarations in header files, rather than cpp files, so any other source can include header file and start using described class. It's OK to include definition for trivial class methods in header file as well (like getters/setters), but complicated methods should be declared in header file and defined in coresponding cpp file.
In your case I would do the following:
HardwareDiagnostic.h describes HardwareDiagnostic class. There is no using std line in this file, so anyone including this file won't implicitly start using undesired namespace. All methods are declared, but not defined.
HardwareDiagnostic.cpp defines methods of HardwareDiagnostic class. So there is using std line and definition of all methods.
Localization.h includes HardwareDiagnostic.h and describes Localization class. Having separate file for each class becomes very convenient as project grows.
Localization.cpp defines methods of Localization class.
Staircase.h and Staircase.cpp are built the same way as localization.
main.cpp includes HardwareDiagnostic.h and Staircase.h
In java there is no header file. We import Class and use function. We can also extend them. In C++ there is header file. We include them and use function. Now my question, how to inherit them like java extends and is it possible?
Every program has its own way of doing something. In c++ you can do like:
//filename foo1.h
class foo1
{
}
Now inn another file say foo2.h
//filename foo2.h
#include "foo1.h"
class foo2 : public foo1
{
}
Java combines two things which C++ separates: the class definition and the definition of its members.
Java:
class Example {
private String s;
protected static int i = 1;
public void f() {
System.out.println("...");
}
public Example() {
s = "test";
}
}
C++ class definition:
class Example
{
private:
std::string s;
protected:
static int i;
public:
void f();
Example();
};
C++ definition of members:
int Example::i = 1;
void Example::f()
{
std::cout << "...\n";
}
Example::Example() :
s("test")
{
}
The separation into *.h and *.cpp files is purely conventional. It typically makes sense to put the class definition into the *.h file and the definition of the members into the *.cpp file. The reason why it makes sense is that some other code using the class only needs the class definition, not the definition of its members. That "other code" includes subclasses. By providing the class definition in a separate file, a user of the class can just #include the header and doesn't need to bother with the *.cpp file.
(Note that the *.cpp file, too, needs to #include its corresponding header file.)
If that looks complicated to you, view it from a different perspective. It allows you to modify the definition of the members without users of your class having to recompile their code. This is a big advantage of C++ compared to Java! The larger your project, the more important an advantage it becomes.
The general way of doing this in c++ with inheritance/polymorphism is by stating the following:
#include "myheaderfile.h"
I know how to define a class method inside of the same file with which the class is in.
For example:
class Robot
{public:
int location;
void Moves(); //Class method to be defined
}
void Robot::Moves()
{//Method definition here }
I do NOT know hot to define a class outside of the file in which the class is in. I tried creating a .hpp file and defining a class method inside of it, but my compiler signified that it could not load a class definition from a file other than the one the class was created in, or it would be as though I was placing a function's definition before the include directives.
Please note: The original class file is also in a .hpp file, as I have yet to learn how to use .cpp files other than the main one.
This is done using C++/Win32.
Create a .cpp file along these guidelines
Include your class header file in your .cpp file
Include all necessary headers you would use in main.cpp
use the scope operator for your class
#include <iostream>
#include "foo.hpp"
foo::foo()
{
// code here
}
void foo::OtherFunc()
{
// other stuff here
}
Just put your definition in a .cpp file and link it with your application.
Robot.hpp:
class Robot
{public:
int location;
void Moves(); //Class method to be defined
}
Robot.cpp:
#include "Robot.hpp"
void Robot::Moves()
{//Method definition here }