I cannot explain why I am getting this logic error! Take a look:
This is in the header -
class PayRoller
{
public:
void initialize();
double getNum();
void setNum(double);
double getGrossPay();
void setGrossPay(double);
double getWage();
void setWage(double);
double getAddTotal();
void setAddTotal(double);
}
And here is the first function that is called after the object is made-
void PayRoller::initialize();
{
setGrossPay(0.0);
setWage(0.0);
setAddTotal(0.0);
cout << (getGrossPay() + getAddTotal());
start();
}
And finally here are the getters and setters-
void PayRoller::setGrossPay(double temp)
{
grossPay = temp;
}
double PayRoller::getWage()
{
return wage;
}
void PayRoller::setWage(double temp)
{
wage = temp;
}
double PayRoller::getAddTotal()
{
return addTotal;
}
void PayRoller::setAddTotal(double temp)
{
wage = temp;
}
When I start the code (without debugging) the value I get from the cout
in initialize() is -9.25596e+061
What am I doing wrong here? I can't seem to figure it out. Thanks in advance!
Your setAddTotal Method is not setting addTotal, its setting wage.
void PayRoller::setAddTotal(double temp)
{
wage = temp;
}
should be
void PayRoller::setAddTotal(double temp)
{
addTotal = temp;
}
Otherwise, addTotal isn't actually set to 0, it just contains garbage.
You need to scrap the initialize() method and use a member initialization list.
What you call as Initialization is actually Assignment, Initialization can be done only in the member initialization list. What you need is initialization, ie: tying up a value to an member at the time of creation not assigning value to the member after creation.
Problem with Assignment approach is that you need to rely on the user of your class to call the methods in your defined way, which they may not.
Seems precesion issue number is almost 0. Try changing the values to long or int and this can be verfied.
Related
I am trying to create the class that can only allow one object to be created at a time, so i have created private constructor and one public wrapper getInstance() method that will create object for this class, the code goes as follows
#include <iostream>
using namespace std;
class sample
{
static int cnt;
int temp;
private: sample()
{
//temp++;
cnt++;
cout<<"Created "<<++temp<<endl;
}
public:
void show()
{
cout<<"Showing \n";
}
static sample* getInstance()
{
cout<<"count is "<<cnt<<endl;
if(cnt<1)
return (new sample());
else
return NULL;
}
};
int sample::cnt=0;
int main()
{
// cout<<"Hello World";
sample *obj = sample::getInstance();
obj->show();
sample *obj1 = sample::getInstance();
if(obj1 == NULL)
cout<<"Object is NULL\n";
obj1->show();
return 0;
}
How is obj1->show() is getting called?
OUTPUT :
count is 0
Created 1
Showing
count is 1
Object is NULL
Showing
In a vacuum, this is just because your function:
public:
void show()
{
cout<<"Showing \n";
}
don't actually try to do anything with the object - to get into the correct mindset of why this works just think of a member function as an abstraction over a free function taking the object as it's first argument:
void show(Object* this)
{
cout<<"Showing \n";
}
Now it is easy to see why this works since you don't use this - the null pointer.
If you change to something ala. this:
public:
void show()
{
cout<< this->temp << "Showing \n";
}
Your program should almost certainly crash.
What is almost certainly happening here is that the compiler is optimizing the call to show by inlining it. Further, it can also make it a "pseudo-static" function, as the there is no reference inside show to any other class member.
To 'break' the optimisation (and cause a crash) you can do one of these:
Decare the show function virtual
Reference a non-static member (e.g. temp) inside the function
Im using C++ to create a timer. Ive look up the internet but not find anything that i can understand.Here is my code:
struct Timer{
bool timerRunning;
int time;
void Timer_Service(void* param){
timerRunning = true;
time = 0;
while(timerRunning){
wait(10);
time += 10;
}
}
void startTimer(){
Timer_Service((void*)"PROS");
pros::Task timerservice(Timer_Service,(void*)"PROS");// <- error here "reference to non-static member function must be called"
}
void stopTimer(){
timerRunning = false;
}
int getTime(){
return time;
}
};
How do i solve this error?
BTW pros::Task timerservice(Timer_Service,(void*)"PROS"); is a function that initializes a multitask loop.
Thanks all for your kind help.
The pros::Task constructor takes a function pointer.
Function pointers and pointers-to-member-functions are not the same thing.
You will have to pass a pointer to a non-member function (or a static member), ideally a forwarding delegate. You can create a class that contains a Timer_Service*, and pass it through the void* argument. In fact, in this case, since you only need to pass the object pointer, there's no need for a wrapping class.
struct Timer
{
bool timerRunning;
int time;
static void Timer_Service_Delegate(void* param) {
Timer* ptr = reinterpret_cast<Timer*>(param);
ptr->Timer_Service();
}
void Timer_Service() {
timerRunning = true;
time = 0;
while(timerRunning){
wait(10);
time += 10;
}
}
void startTimer() {
pros::Task timerservice(
Timer_Service_Delegate,
reinterpret_cast<void*>(this)
);
}
void stopTimer() {
timerRunning = false;
}
int getTime() {
return time;
}
};
I suspect you'll also need to keep the pros::Task in scope, but I don't know enough about the library to train you on that. Refer to its documentation.
To avoid code duplication, I'm tring to pass pointers to functions as arguments of a static method.
I have a class (Geo) with only static methods. One of this methods (+++Geo::traceRay(+++)) should just display(Geo::display(+++)) few things, then return an int.
Another class (Las) needs to use the Geo::traceRay(+++) method, but should display(Las::display(+++)) someting else.
So I try to pass a pointer to function argument to the Geo::traceRay(+++, pointer to function) method. the pointed functon will the right "display()" method.
Up to now, passing the first pointer to display() is not an issue, but I can't find how to do it with the second one.
class Geo
{
public:
static bool display(int pix);
static int traceRay(int start, int end, bool (*func)(int) = &Geo::display); // no issue with this default parameter
};
class Las
{
public:
bool display(int pix);
void run();
};
int Geo::traceRay(int start, int end, bool (*func)(int))
{
for (int i = start; i < end ; ++i )
{
if((*func)(i)) return i;
}
return end;
}
bool Geo::display(int pix)
{
cout << pix*100 << endl;
return false;
}
bool Las::display(int pix)
{
cout << pix << endl;
if (pix == 6) return true;
return false;
}
void Las::run()
{
bool (Las::*myPointerToFunc)(int) = &display; // I can just use display as a non member class, but it should stay a member
Geo::traceRay(0,10, myPointerToFunc); // issue here!
}
int main()
{
Geo::traceRay(0,10); // use the "normal display" = the default one// OK
Las myLas;
myLas.run();
return 0;
}
You can't pass a member function pointer as a function pointer. I presume making Las::display static is not an option. In that case, I would suggest taking a std::function and using std::bind to bind the current instance:
static int traceRay(int start, int end, std::function<bool(int)> func = &Geo::display);
...
Geo::traceRay(0,10, std::bind(&Las::display, this, std::placeholders::_1));
Also, in both cases, you can call func by:
func(i);
No need to dereference it first.
What Chris suggests is great if that's as far as it goes.
Another approach to this, which would be beneficial if you have several shared functions like that, would be to use an interface (with a virtual method Display(+++)) with two implementations, put an instance of the implementation in question in each of Geo and Las (or Las could directly implement the interface). Then traceRay takes a reference to the interface base class and calls the display method on it.
I have narrowed my problem down to passing 2 objects (which contain pointer data members) to a simple void function. The function returns clean, but when main() attempts to exit, it can not reclaim the first of the 2 objects. Here is a sample piece of code that shows the issue - along with print statements to show the address's of the objects as they are constructed, passed, and destructed.
If I only call "print1" - the program runs fine. However, if I call "printboth" - then the object "myNumbers" can not be freed. I can also make the error go away by removing the destructor statement:
delete [] number;
but I don't think this is a good idea.
Anyone have any ideas?
class dummy
{
public:
dummy() {
number = new int[1];
currentPos = -1;
std::cout<<"default constructor called for "<<this<<std::endl;
}
dummy(int len) {
number = new int[len];
currentPos = -1;
std::cout<<"parameterized constructor called for "<<this<<std::endl;
}
~dummy() {
cout<<"Calling destructor for "<<this<<endl;
delete [] number;
}
int getNextNumber() {
currentPos++;
return number[currentPos];
}
void setNumbers(int position, int value) {
number[position] = value;
}
private:
int* number;
int currentPos;
};
void print1(dummy);
void printboth(dummy, dummy);
int main() {
dummy myNumbers(3);
myNumbers.setNumbers(0,0);
myNumbers.setNumbers(1,1);
dummy myOtherNumbers(3);
myOtherNumbers.setNumbers(0,4);
myOtherNumbers.setNumbers(1,5);
cout<<"Address of myNumbers is "<<&myNumbers<<endl;
cout<<"Address of myOtherNumbers is "<<&myOtherNumbers<<endl;
print1(myNumbers);
printboth(myNumbers, myOtherNumbers);
system("PAUSE");
return 0;
}
void print1(dummy num) {
cout<<"Address of num is "<<&num<<endl;
for (int i=0;i<4;i++)
cout<<"Dummy number1 is "<<num.getNextNumber()<<endl;
return;
}
void printboth(dummy num1, dummy num2) {
cout<<"Address of num1 is "<<&num1<<endl;
cout<<"Address of num2 is "<<&num2<<endl;
for (int i=0;i<4;i++) {
cout<<"Dummy number1 is "<<num1.getNextNumber()<<endl;
cout<<"Dummy number2 is "<<num2.getNextNumber()<<endl;
}
return;
}
You didn't follow rule of three
The problem is that when you call print1 or printboth the compiler calls the default copy-constructor (since you didn't provide one). That copy-constructor sets the number member variable of the copy to the same value as the original. When the destructor is called on the copy, the memory is released. Your original object now points to memory that has already been released so when its destructor is called, you crash(Nik Bougalis).
void print1(dummy);
void printboth(dummy, dummy);
You could pass dummy by const reference to avoid unnecessary copy, but strong recommand you follow rule of three
void print1(const dummy& );
void printboth(const dummy&, const dummy&);
Note:
You only created size =1 array which is not necessary at all, just use int number; as member. If number holds dynamically allocated array, try use std::vector<int>.
getNextNumber is flawed, when it's called multiple times, number[currentPos]; access boundry out of number which is undefined behavior.
int getNextNumber() {
currentPos++;
return number[currentPos];
}
Which implies what suggested:
int getNextNumber() const {
return number[currentPos];
}
I have a vector of vertices and I wish to set vertice.setVisit as false or 0 initially. I defined some getters and setters for this, but getting some type error. Code is as per below:
//Vector:
std::vector<project3::Vertex<VertexType, EdgeType>*> Vertice1;
//Class containing methods:
template <class VertexType, class EdgeType> class Vertex{
protected:
//std::vector<std::pair<int, EdgeType>> VertexList;
VertexType vertice;
EdgeType edge;
int num;
int mark;
//int status=0;
public:
void setNum(int){ this.num = num; }
int getNum() { return num; }
int getMark(){ return mark; }
void setVisit(int) { this.mark = mark; }
};
In some function I am assigning the values to it as :
for(int i=0; i<g1.Vertice1.size(); i++)
{
g1.Vertice1.at(i)->setNum(0);
g1.Vertice1.at(i)->setVisit(0);
}
Below is the error I am getting while compilation of the code for "this.mark=mark" and for "this.num=num" in the function definition in class.
Error: left of '.mark' must have class/struct/union
Error: left of '.num' must have class/struct/union
Isn't this the correct way to assign the values through getter and setters?
In C++, this is a pointer-type. Try this->mark or (*this).mark
EDIT: As Richard pointed out below, also be sure to name your parameters which you are trying to assign. In context, this->mark = mark is the same thing as this->mark = this->mark. Unless mark is a parameter, this is really unnecessary in this case. So realistically, you can get rid of this all together in your example by doing something like this:
void setVisit(int newMark) { mark = newMark; }
Regards,
Dennis M.
Change setNum and setVisit to the following
void setNum(int num) {this->num = num; }
void setVisit(int mark) {this->mark = mark; }
this is a pointer, so you have to use this->num.