C++: Error with 'this' keyword - c++

I am attempting to create an poptart vending machine program within c++ and i am trying to use the this keyword, however i am always getting an error stating 'this' may only be used inside a nonstatic member function. Below is a part of the code that i am getting one such issue in
Code:
#include <iostream>
#include "HasCredit.h"
using namespace std;
void insertMoney(int money)
{
cout<<"You inserted: " << money;
money = money+this->currentContext->getStateParam(Credit);
this->currentContext->setStateParam(Credit,money);
cout<< "Total: "<<money<<endl;
this->currentContext->setState(Has_Credit);
}
Any suggestions onto why i am getting this error will be most appreciated. Cheers.
Edit: the insertMoney method is within a class called HasCredit.
Edit2: member declarations are now made outside of the constructor
Edit3: Added state class declaration
The Class Definition Code is Below:
#include <iostream>
#include "State.h"
#include "StateContext.h"
using namespace std;
class HasCredit: public State
{
HasCredit (StateContext* Context) : State(Context) {
}
void insertMoney(int);
void MakeSelectionCoating(int);
void MakeSelectionFilling(int);
void moneyRejected(void);
void addPopTarts(int);
void dispense(void);
};
The state class declaration code is shown Below:
#include <iostream>
#include "Transition.h"
using namespace std;
class State: public Transition
{
protected:
StateContext* currentContext;
public:
State(StateContext* Context);
};

The this pointer is only valid inside a class. Your insertMoney function is not declared to be in a class. See http://www.learncpp.com/cpp-tutorial/87-the-hidden-this-pointer/.
In your definiton of insertMoney (in the code, not the class), you do not declare it to be a member of hasCredit. You need to use void hasCredit::insertMoney instead.

You probably want to attach insertMoney to a class. Try ClassName::insertMoney in your definition.

The error is telling you exactly why you're getting it.
The solution is to fix the definition of what you intend to be a member function, so that the compiler knows it is a member function. Like this:
// vv THIS WAS MISSING
void HasCredit::insertMoney(int money)
{
...
Your member declarations shown in the question are also in the wrong place. They need to be inside the class body, but outside the constructor. When overriding virtual member functions, you may want to show that to readers by using the virtual and override keywords. (Note, override only works if you have a new, C++11 compiler. For older compilers, use a comment /* override */ instead)
class HasCredit: public State
{
HasCredit (StateContext* Context) : State(Context) { }
// vv THIS....................CANNOT BE INSIDE HERE ^^
virtual void insertMoney(int) override;
...
};
You probably want some of your members to be public as well.

There are a few things wrong:
class definition:
#include <iostream>
#include "State.h"
#include "StateContext.h"
using namespace std;
class HasCredit: public State
{
HasCredit (StateContext* Context) : State(Context) {
}
void insertMoney(int);
void MakeSelectionCoating(int);
void MakeSelectionFilling(int);
void moneyRejected(void);
void addPopTarts(int);
void dispense(void);
};
Note that the methods should be declared outside of the constructor definition.
For the implemenation:
#include <iostream>
#include "HasCredit.h"
using namespace std;
void HasCredit::insertMoney(int money)
{
cout<<"You inserted: " << money;
money = money+this->currentContext->getStateParam(Credit);
this->currentContext->setStateParam(Credit,money);
cout<< "Total: "<<money<<endl;
this->currentContext->setState(Has_Credit);
}
The method must be qualified with the name of the class... otherwise it would be considered a definition of a function... and a function does not have a this

Related

trouble with accessing a class from a different class

just started to learn c++.I'm trying new things in c++ on thing i wanted to try is to access a class from another class and change its instances and print its instance on screen.
I would like to know 2 things 1)whats wrong with my code 2)where should i declare class declarations (in main file or class definition file?)
here is the error log -
'object::carrier' uses undefined class 'sub'
'cout': is not a member of 'std'
'cout': undeclared identifier
this is what i came up with-
source.h
#include <iostream>
#include <vector>
#include "stuff.h"
int main()
{
object spoon(3);
spoon.get();
}
stuff.cpp
#pragma once
#include <vector>
class object;
class sub;
class object
{
private:
std::vector <sub> thing;
public:
object(int n);
void get() const;
};
class sub
{
private:
int num;
public:
void set_num(int n);
};
stuff.cpp
#include <vector>
#include "stuff.h"
// methods for object
object::object(int n)
{
sub carrier;
carrier.set_num(n);
}
void object::get() const
{
std::cout << carrier.num;
}
// methods for sub
void sub::set_num(int temp_num)
{
num = temp_num;
}
thanks
In your object class, specifically object::get definitions, you use the variable carrier without it being in scope.
When you declare the variable sub carrier in your constructor, it is only accessible in the same scope, that is, inside the constructor. Once your program leaves the scope, the variable carrier is deallocated (deleted).
You must add the variable sub carrier as a member to your class like so:
class object
{
private:
sub carrier
// other stuff
}
Edit:
I so you edited your question.
You must either replace cout with std::cout because cout is part of the c++ standard library. Alternatively, a less verbose option would be to add using namespace std; at the top of every .cpp file. This basically tells the compiler that you can use the namespace std without explicitly saying it. But don't do it for .h files. It's not a good idea.

Member function definition outside the class

Firstly, I am giving the codes. Then I am explaining the problem I am facing.
main.cpp
#include <iostream>
#include "acc.h"
using namespace std;
class mem;
int main()
{
show();
return 0;
}
acc.h
#ifndef ACC_H
#define ACC_H
#include "acc.cpp"
void show();
class mem{
int a;
public:
void showa();
void seta(int A);
};
#endif
acc.cpp
#include <iostream>
using namespace std;
void mem::showa(){cout<<a<<endl;}
void mem::seta(int A){a = A;}
void show()
{
mem m;
m.seta(22);
string ss;
cin>>ss;
cout<<"MY name is "<<ss<<" ";
m.showa();
}
"mem" class I declared in "acc.h" file already and added that "acc.h" into acc.cpp file also. But when I am calling that class from a function. It can't response. Showing "a" and "mem" not declared. How can I perfectly link that class definition and member functions of that class so that calling member functions of that class from another function can't create any problem?
If you remove the #include "acc.cpp" from the acc.h file it should compile without any errors. I tried and it compiles for me. I am using Visual Studio 2010 for the same.
Other than this, few more comments:
You can use #pragma once in you header file instead of #ifndef/#define macros. The former is more cleaner.
You dont need to forward declare class mem before main() as you are already including acc.h.
the show() can be moved to where main() is defined making the acc.h/acc.cppfiles dedicated for the mem class.
A header file should always be named after the class it is holding i.e. mem.h/mem.cpp in your case. This informs which file contains which class even without opening the file.

Error with dynamic_cast

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"

Passing objects by reference in C++

I am trying to pass an object (of class Stock) by const reference to a function of another class (called Algorithms).
//Algorithms.h
#pragma once
class Algorithms
{
public:
Algorithms(void);
~Algorithms(void);
int Algorithms::doAnalysis(const Stock&);
};
The implementation of doAnalysis is
#include "StdAfx.h"
#include "Algorithms.h"
#include "Stock.h"
#include <vector>
using namespace std;
Algorithms::Algorithms(void)
{
}
Algorithms::~Algorithms(void)
{
}
int Algorithms::doAnalysis(const Stock &S)
{
//Do Something
return 0;
}
The class Stock has the following constructors
public:
Stock(std::string market, std::string symbol);
Stock(std::string market, std::string symbol, std::string start_date, std::string end_date);
I am getting the following error:
Error: declaration is imcompatible with "int Algorithms::doAnalysis(const<error-type> &)" declared at line 8 of Algorithms.h
I understand that the class Stock is not being found. How should I declare the doAnalysis method in Algorithms.h so that it is found? Stock is not a derived class.
Thanks for your help. I am new to C++.
You have to add a forward declaration of the class Stock:
// Forward declaration
class Stock;
class Algorithms
{
public:
Algorithms(void);
~Algorithms(void);
int doAnalysis(const Stock&);
// ^^ <- Remove the Algorithms::
};
You can see here why a forward declaration is necessary in C++.
Put a forward declaration outside your class declaration:
class Stock;
class Algorithms
{
// ...
You could also just add #include "Stock.h" in Algorithms.h file and remove the include from the cpp file. Also you don't need Algorithms:: in the declaration of doAnalysis in Algorithms.h

C++ what to code if i put a class after main() function

I'm watching some video tutorials on C++ and i know you must define a function / class before it is used or called. But I like having my main() function at the top, and everything else below the main function. I know if i define a function below the main function I must declare it before it is used, but what about a class? What do I need to put above my main function to use my class below the main function.
#include <iostream>
using namespace std;
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
I tried defining my class by placing this right before main():
class ClassOne;
but it doesn't work.
This is why header files are normally used in C++. When you're saying ClassOne one, the compiler needs to know what the class looks like to create an object of that type. It's not enough to know that the class exists somewhere (that is enough if all you want is a pointer). So the compiler needs to already have read the definition of the class.
Your class has to be defined before it is first used. Without putting it explicitly before main, the usual way is to create a header file. So you create ClassOne.h with the class declaration, and you have #include "ClassOne.h at the top of your file. In this situation the actual methods of the class would normally be in another source file, ClassOne.cpp.
A class MUST be "complete" when you create an instance of it. So there is no way you can use the class before you have defined the whole content of the class.
It is possible to do something like this:
class ClassOne;
ClassOne* make_class_one();
void use_class(ClassOne *x);
int main()
{
ClassOne* one = make_class_one();
use_class(one);
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
ClassOne* make_class_one()
{
return new ClassOne; // Bad idea, use uniqe_ptr, but I'm lazy.
}
void use_class(ClassOne *x)
{
x->coolSaying();
}
But in general, we don't want to do that.
One scenario where the class definition after the main() function makes sense:
#include <iostream>
using namespace std;
void f();
int main()
{
f();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
void f()
{
ClassOne one;
one.coolSaying();
}
(note: all other answers are correct, but you may find this useful)
I discovered this idiom to invert the order of main and secondary function classes. I use to share small code with colleagues, everybody expects the core of the code (i.e. main) to be on top so they can edit it quickly. It works with classes and functions (without need of declaration) of course. Usually I can leave the preamble (first #includes) because those have include guards in most cases.
#include <iostream>
using namespace std;
#ifdef please_see_definitions_below_main
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
#else
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
#define please_see_definitions_below_main
#include __FILE__
#endif
I use the tag please_see_definitions_below_main so it serves as comment also, but if you don't like it you can use something shorter, like AFTER.
You cannot create an actual instance of the type (variable, value member) until the type is fully defined, as its size is not known. There is no way around that, but there is a lot you can already do with a pointer to an incomplete type.