Why is the method payment1 giving a different outpout then payment2? payment2 has the same argument name then the method name (I hope I'm saying this right?). I mean that the code this->moneysamename+=moneysamename;. Why can't the compiler differentiate the 2 variables?
Here's the full code:
#include <iostream>
using namespace std;
class Person
{
protected:
static int money;
static int moneysamename;
public:
virtual void payment1(float money1) = 0;
virtual void payment2(float moneysamename) = 0;
};
class Worker : public Person
{
public:
virtual void payment1(float moneyanothername)
{
this->money+= moneyanothername;
cout << "Worker: " << money << endl;
};
virtual void payment2(float moneysamename)
{
this->moneysamename+= moneysamename;
cout << "Worker: " << moneysamename << endl;
};
};
void pay1(Person &m, float sum)
{
m.payment1(sum);
}
void pay2(Person &m, float sum)
{
m.payment2(sum);
}
int Person::money = 0;
int Person::moneysamename = 0;
int main()
{
Worker Gaston;
pay1(Gaston, 200);
pay1(Gaston, 300);
pay2(Gaston, 200);
pay2(Gaston, 300);
}
output:
Worker: 200
Worker: 500
Worker: 200
Worker: 300
Your problem is you are not printing the static variable in payment2 but instead you are printing the local function variable
cout << "Worker: " << moneysamename << endl;
Since in the above line you did not use this-> like you do in
this->moneysamename+= moneysamename;
You get the function local moneysamename and not the static member variable. Change the output to
cout << "Worker: " << this->moneysamename << endl;
and you will get the same output.
The reason you do not get this in payment1 is the function paramter has a different name then the static variable. Had you made the function
virtual void payment1(float money)
{
this->money+= money;
cout << "Worker: " << money << endl;
};
You would have had the same results.
virtual void payment2(float moneysamename)
{
this->moneysamename+= moneysamename;
cout << "Worker: " << moneysamename << endl;
};
Here inside payment2, moneysamename will always refer to the function's first argument by C++ scoping rules (the nearest definition is taken). Hence, always the function's argument will be printed instead of the static protected variable of the parent class with the same name.
To print the local parent's variable you have to go to it's scope by cout << "Worker: " << this->moneysamename << endl;
Related
I'm still learning C++ so go easy on me.
Is there a way I can pass an object to a method without specifying an object? I'm probably butchering the terms so ill show code.
class Student
{private:
std::string Name;
float GPA;
char Sex;
int Absentee;
int *Data ;
public:
std::string GetName();
float GetGPA();
char GetSex();
int GetAbsentee();
void SetData(int);
int GetData();
int *GetDataAddr();
//Methods
void DisplayStudent(Student);
void Student::DisplayStudent(Student Stud)
{
std::cout << "___________________________________" << std::endl;
std::cout << "Name :" << Stud.GetName() << std::endl;
std::cout << "GPA :" << Stud.GetGPA() << std::endl;
std::cout << "Sex :" << Stud.GetSex() << std::endl;
std::cout << "Absentee :" << Stud.GetAbsentee() << std::endl;
std::cout << "Data :" << Stud.GetData() << std::endl;
std::cout << "Data Add :" << Stud.GetDataAddr() << std::endl;
std::cout << "___________________________________" << std::endl;
}
int main() {
Student Spike("Spike", 3.9f, 'M', 43,55);
* Compiles fine: Spike.DisplayStudent(Spike);
* DOSNT Compile: Student DisplayStudent(Spike);
* C++ a nonstatic member reference must be relative to a specific object*
return 0;
}
So the question I have is at least with this method, why do I need to specify or rather, what is the purpose of "Spike" in "Spike.DisplayStudent(.....)"? Student::Display(.....) makes far more sense to me.
If your Student::DisplayStudent is designed to display information for the student who is represented by that class instance, you don't need to pass Student Stud at all, just use member variables.
If however it is designed to display info for ANY student - you can make it a static member, or a free-standing function.
If you want the member function DisplayStudent to display the information for the very instance of Student on which the function is called, you do not need to pass a Student as an argument.
class Student {
public:
// The getter methods should be `const`, since calling them does not change
// the `Student`:
const std::string& GetName() const; // return a `const&` to avoid unecessary copying
void DisplayStudent() const; // No `Student` argument, like in `GetName()`
// ...
};
void Student::DisplayStudent() const {
std::cout << "___________________________________\n"
"Name :" << GetName() << "\n"
"GPA :" << GetGPA() << "\n"
"Sex :" << GetSex() << "\n"
"Absentee :" << GetAbsentee() << "\n"
"Data :" << GetData() << "\n"
"Data Add :" << GetDataAddr() << "\n"
"___________________________________\n";
}
You also do not need to call getter methods in DisplayStudent() since you have access to the private member variables and do not need to do any calculations before returning the result.
Usage example (if the appropriate constructor exists as you've indicated):
int main() {
Student Spike("Spike", 3.9f, 'M', 43,55);
Spike.DisplayStudent(); // no instance passed as an argument
}
So as the title suggests I am attempting to change the number variable, originally stored as 1000. Change this variable in another class function, and then replace the original value (1000) with the newly updated number. I haven't been able to find anything online to help me with this.
I have tried using pointers to no avail.
#include <iostream>
using namespace std;
class data {
protected:
int number = 1000;
};
class fetchData : public data {
public:
int getNumber() {
return number;
}
int updateNumber(int newNumber) {
number = newNumber;
return number;
}
};
class function : public fetchData {
public:
void minusNumber(int numberTakeAway) {
int newNumber = number - numberTakeAway;
updateNumber(newNumber);
cout << "Taken away: " << numberTakeAway << endl;
cout << "\nShould be new number: " << number << endl; // Not updating parent class variable
}
};
void printData() {
fetchData r;
cout << "number: " << r.getNumber() << endl;
}
void minusNumber() {
function r;
r.minusNumber(200);
}
int main(void) {
fetchData q;
cout << "\nOriginal ";
printData();
cout << "\n";
minusNumber();
cout << "\nActual ";
printData();
cout << "\n";
return 0;
}
You seem to be confusing between static - class members, and non static - instance members.
number is an instance member which means every instance will have its own number with its own value.
Each of your functions main, printData, and minusNumber creates its own instance of function or fetchData class, and there is no connection between them.
Try this code, where there is only one instance:
int main(void) {
function q;
cout << "\nOriginal ";
q.printData();
cout << "\n";
q.minusNumber(200);
cout << "\nActual ";
q.printData();
cout << "\n";
return 0;
}
What you have done in the free functions is to create a new instance of your class. If you want to do something with q that you instantiated in main, you have to pass it. Or use the member function in your class. So below, I've changed printData to take a reference to q. And instead of calling the free function minusNumber, I've called the member function of your class. I deleted the free function as it is not used.
#include <iostream>
class data {
protected:
int number = 1000;
};
class fetchData : public data {
public:
int getNumber() const {
return number;
}
int updateNumber(int newNumber) {
number = newNumber;
return number;
}
};
class function : public fetchData {
public:
void minusNumber(int numberTakeAway) {
int newNumber = number - numberTakeAway;
updateNumber(newNumber);
std::cout << "Taken away: " << numberTakeAway << std::endl;
std::cout << "\nShould be new number: " << number << std::endl; // Not updating parent class variable
}
};
void printData(const function& r) {
std::cout << "number: " << r.getNumber() << std::endl;
}
int main(void) {
function q;
std::cout << "\nOriginal ";
printData(q);
std::cout << "\n";
q.minusNumber(200);
std::cout << "\nActual ";
printData(q);
std::cout << "\n";
return 0;
}
Hi this is the header file for my base class Ranger, and in it I have protected variables fov_, usb_ ... that I wish to access with my getter functions, I have three child classes on this one.
Ranger.h
#ifndef RANGER_H
#define RANGER_H
using namespace std;
class Ranger
{
//private contructor prevents contruction of base class
Ranger();
public:
void setBaud(int baud);
virtual void setFOV(int fov) = 0;
void setSamp(int sam);
int getFOV();
int getBaud();
int getMaxRange();
int getUSB();
protected:
//protected variables that are each indivdualy owned by each sensor
int fov_;
int maxRange_;
int usb_;
int baud_;
int samp_;
double data[];
//protected contructors for the child classes to use to set fixed parameters
Ranger(int fov, int maxRange, int port);
Ranger(int maxRange, int port);
};
#endif // RANGER_H
This is my cpp file for the base class that includes the getter files, it just has a return of the portected variables.
Ranger::Ranger()
{
}
Ranger::Ranger(int fov, int maxRange, int port)
{
fov_ = fov;
maxRange_ = maxRange;
usb_ = port;
}
Ranger::Ranger(int maxRange, int port)
{
maxRange_ = maxRange;
usb_ = port;
}
void Ranger::setBaud(int baud)
{
switch(baud)
{
case 0: baud_ = 38400; break;
case 1: baud_ = 115200; break;
default: baud_ = 38400; break;
}
}
void Ranger::setSamp(int sam)
{
samp_ = sam;
}
int Ranger::getFOV()
{
return fov_;
}
int Ranger::getBaud()
{
return baud_;
}
int Ranger::getMaxRange()
{
return maxRange_;
}
int Ranger::getUSB()
{
return usb_;
}
And in my main I want to access the protected variables from the base class to prevent re writting code, so each childs variables are protected in the base class. I try to access these by las.getFOV() but I get a segmentation fault error meaning I don't have access to them, and I don't quite understand why.
main.cpp
int main( int argc, char ** argv)
{
Laser las;
int baud;
cout << "Baud:" << endl;
cout << "0 - 38400" << endl;
cout << "1 - 115200" << endl;
cin >> baud;
las.setBaud(baud);
cout << "Baud for Lazer sensor is "+las.getBaud() << endl;
cout << "Lazer sensor created..." << endl;
cout << "Lazer's FOV: " + las.getFOV() << endl;
cout << "Lazer's Max Range: " + las.getMaxRange() << endl;
cout << "Lazer's Port: " + las.getUSB() << endl;
Radar rad;
int baud2;
cout << "Baud:" << endl;
cout << "0 - 38400" << endl;
cout << "1 - 115200" << endl;
cin >> baud2;
rad.setBaud(baud2);
cout << "Baud for Radar sensor is "+rad.getFOV() << endl;
int fov;
cout << "Feild of View Of Radar:" << endl;
cout << "0 - 20 degrees" << endl;
cout << "1 - 40 degrees" << endl;
cin >> fov;
rad.setFOV(fov);
cout << "FOV is set to " + rad.getFOV() << endl;
cout << "Radar sensor created..." << endl;
cout << "Radar's FOV: ' " + rad.getFOV() << endl;
cout << "Radar's Max Range: " + rad.getMaxRange() << endl;
cout << "Radar's Port: " + rad.getUSB() << endl;
Sonar son;
//rad.setFOV(user);
}
and here is one of the child class's cpp file for reference (Lazer)
laser.cpp
#include "laser.h"
Laser::Laser() : Ranger(180,8,0)
{
};
void Laser::setFOV(int fov)
{
fov_ = fov;
}
laser.h
#ifndef LASER_H
#define LASER_H
#include "ranger.h"
#include "rng.h"
class Laser : public Ranger
{
public:
Laser();
void setFOV(int fov);
};
#endif // LASER_H
Thanks everyone who commented, I understand I put way too much code to help you guys out, sorry about that I'll know for next time, and thankyou to letting me know the difference between the errors, I've done more research and found that the issue was when I was printing it out you can't use operators like:
cout<<""+function()<<endl;
Instead you need to separate the functions from the array like so:
cout<<""<<function()<<endl;
Thanks guys.
First off: I know that it is generally a bad idea to change an object's class, but I'm implementing my own programming language, and it has variables that can contain values of any type, and even change their type at will, so please assume I'm not a beginner not understanding OO basics.
Currently, I implement my variant variables in C. Each one has a pointer to a table of function pointers, containing functions like SetAsInt(), SetAsString() etc., followed by what would be instance variables in C++. All objects are the same size.
When a variable contains a string and someone assigns an Int to it, I manually call the destructor, change the table of function pointers to point to the table used for variadic int values, and then set its int instance variable.
This is a bit hard to maintain, as every time I add a new type, I have to add a new table of function pointers and fill out all the function pointers in it. Structs of function pointers seem to be very badly type-checked, and missing fields don't lead to complaints, so I can easily accidentally forget one pointer in the list and get interesting crashes. Also, I have to repeat all the function pointers that are the same in most types.
I'd like to implement my variadic types in C++ instead, where a lot of this type-checking and inheriting default behaviours is done for me by the compiler. Is there a safe way to do this?
PS - I know I could create a wrapper object and use new to allocate a new object, but I can't have the additional extra allocation overhead for every int variable on the stack.
PPS - The code needs to be portable across Linux, Mac, iOS and Windows for now, but if someone has a standard C++ solution, that would be even better.
PPPS - The list of types is extensible, but predetermined at compile-time. The base layer of my language defines just the basic types, but the host application my language is compiled into adds a few more types.
Usage Example:
CppVariant someNum(42); // Creates it as CppVariantInt.
cout << "Original int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsInt(700); // This is just a setter call.
cout << "Changed int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsDouble(12.34); // This calls destructor on CppVariantInt and constructor on CppVariantDouble(12.34).
cout << "Converted to Double: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl; // GetAsInt() on a CppVariantDouble() rounds, or whatever.
(Imagine that beyond double and int, there would be other types in the future, like strings or booleans, but the caller of GetAsInt()/SetAsInt() shouldn't have to know what it is stored as, as long as it can be converted at runtime)
Here is a solution based on type-erasure, union and template specializations.
I'm not sure it fits your requirements.
Anyway, here is what it gets:
Anything is placed on the dynamic storage
No hierarchy required
You can easily improve it further to reduce the amount of code, but this aims to serve as a base point from which to start.
It follows a minimal, working example based on the intended use in the question:
#include<iostream>
class CppVariant {
union var {
var(): i{0} {}
int i;
double d;
};
using AsIntF = int(*)(var);
using AsDoubleF = double(*)(var);
template<typename From, typename To>
static To protoAs(var);
public:
CppVariant(int);
CppVariant(double);
int getAsInt();
double getAsDouble();
void setAsInt(int);
void setAsDouble(double);
private:
var data;
AsIntF asInt;
AsDoubleF asDouble;
};
template<>
int CppVariant::protoAs<int, int>(var data) {
return data.i;
}
template<>
int CppVariant::protoAs<double, int>(var data) {
return int(data.d);
}
template<>
double CppVariant::protoAs<int, double>(var data) {
return double(data.i);
}
template<>
double CppVariant::protoAs<double, double>(var data) {
return data.d;
}
CppVariant::CppVariant(int i)
: data{},
asInt{&protoAs<int, int>},
asDouble{&protoAs<int, double>}
{ data.i = i; }
CppVariant::CppVariant(double d)
: data{},
asInt{&protoAs<double, int>},
asDouble{&protoAs<double, double>}
{ data.d = d; }
int CppVariant::getAsInt() { return asInt(data); }
double CppVariant::getAsDouble() { return asDouble(data); }
void CppVariant::setAsInt(int i) {
data.i = i;
asInt = &protoAs<int, int>;
asDouble = &protoAs<int, double>;
}
void CppVariant::setAsDouble(double d) {
data.d = d;
asInt = &protoAs<double, int>;
asDouble = &protoAs<double, double>;
}
int main() {
CppVariant someNum(42);
std::cout << "Original int: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
someNum.setAsInt(700);
std::cout << "Changed int: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
someNum.setAsDouble(12.34);
std::cout << "Converted to Double: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
}
On a lark, I tried using placement new to do this, and I have ... something ... It compiles, it does the job, but I'm not sure if it's an improvement over pure C. Since I can't have a union of C++ objects, I create a CPPVMAX() macro to pass the largest sizeof() of all subclasses as the size to mBuf[], but that's not really pretty either.
#include <iostream>
#include <string>
#include <cmath>
#define CPPVMAX2(a,b) (((a) > (b)) ? (a) : (b))
#define CPPVMAX3(a,b,c) CPPVMAX2((a),CPPVMAX2((b),(c)))
using namespace std;
class CppVariantBase
{
public:
CppVariantBase() { cout << "CppVariantBase constructor." << endl; }
virtual ~CppVariantBase() { cout << "CppVariantBase destructor." << endl; }
virtual int GetAsInt() = 0;
virtual double GetAsDouble() = 0;
virtual void SetAsInt( int n );
virtual void SetAsDouble( double n );
};
class CppVariantInt : public CppVariantBase
{
public:
CppVariantInt( int n = 0 ) : mInt(n)
{
cout << "CppVariantInt constructor." << endl;
}
~CppVariantInt() { cout << "CppVariantInt destructor." << endl; }
virtual int GetAsInt() { return mInt; }
virtual double GetAsDouble() { return mInt; }
virtual void SetAsInt( int n ) { mInt = n; }
protected:
int mInt;
};
class CppVariantDouble : public CppVariantBase
{
public:
CppVariantDouble( double n = 0 ) : mDouble(n)
{
cout << "CppVariantDouble constructor." << endl;
}
~CppVariantDouble()
{
cout << "CppVariantDouble destructor." << endl;
}
virtual int GetAsInt()
{
if( int(mDouble) == mDouble )
return mDouble;
else
return round(mDouble);
}
virtual double GetAsDouble() { return mDouble; }
virtual void SetAsDouble( int n ) { mDouble = n; }
protected:
double mDouble;
};
class CppVariant
{
public:
CppVariant( int n = 0 ) { new (mBuf) CppVariantInt(n); }
~CppVariant() { ((CppVariantBase*)mBuf)->~CppVariantBase(); }
operator CppVariantBase* () { return (CppVariantBase*)mBuf; }
CppVariantBase* operator -> () { return (CppVariantBase*)mBuf; }
protected:
uint8_t mBuf[CPPVMAX3(sizeof(CppVariantBase),sizeof(CppVariantInt),sizeof(CppVariantDouble))];
};
void CppVariantBase::SetAsInt( int n )
{
this->~CppVariantBase();
new (this) CppVariantInt(n);
}
void CppVariantBase::SetAsDouble( double n )
{
this->~CppVariantBase();
new (this) CppVariantDouble(n);
}
int main(int argc, const char * argv[]) {
CppVariant someNum(42);
cout << "Original int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsInt(700); // This is just a setter call.
cout << "Changed int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsDouble(12.34); // This changes the class to CppVariantDouble.
cout << "Converted to Double: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
return 0;
}
I want to display the objects of the class and the number of objects by using a static function. I typed this code but it does not work. It gives an error Too many types indeclaration" and "undefined symbol getCount. Can anyone help me? where is actually error in this code?
#include<iostream>
#include<string>
class Bag {
private:
static int objectCount;
int Weight;
std::string Brand;
std::string Type;
std::string Material;
std::string Colour;
public:
Bag(int W, std::string B, std::string T, std::string M, std::string C) {
Weight = W;
Brand = B;
Type = T;
Material = M;
Colour = C;
objectCount++;
}
void print() {
std::cout << "\n";
std::cout << "Bag: \n\n";
std::cout << "Weight:\t\t" << Weight << "kg" << '\n';
std::cout << "Brand:\t\t" << Brand << '\n' << "Type:\t\t" << Type << '\n';
std::cout << "Material:\t" << Material << '\n' << "colour:\t\t" << Colour << std::endl;
}
static int getCount() {
return objectCount;
}
};
int Bag::objectCount = 0;
int main() {
Bag bag_1(2, "Slazanger", "Atheletic Bag", "Polyethylene", "Brown");
bag_1.print();
std::cout << "object count " << Bag::getCount() << '\n';
Bag bag_2(4, "Samsonite", "Travel Bag", "Synthetic Fibre", "Gray");
bag_2.print();
std::cout << "object count " << Bag::getCount() << '\n';
Bag bag_3(5, "Herschel", "Duffel bag", "Leather", "Black");
bag_3.print();
std::cout << "object count " << Bag::getCount() << '\n';
Bag bag_4(3, "Kewin Woods", "Hand Bag", "Fibre", "Blue");
bag_4.print();
std::cout << "object count " << Bag::getCount() << std::endl;
while(!std::cin.get());
return 0;
}
You are scoping it incorrectly, getCount is statically scoped to the translation
unit, not the class. Thus it has no symbol named objectCount available to it.
To fix it, merely put the method inside the class.
class Bag {
private:
static int objectCount;
int Weight;
string Brand,Type,Material,Colour;
public:
Bag(int W ,string B ,string T,string M,string C)
{
Weight=W;
Brand=B;
Type=T;
Material=M;
Colour=C;
objectCount++;
}
void print()
{
cout<<"\n";
cout<<"Bag: \n\n";
cout<<"Weight:\t\t"<<Weight<<"kg"<<endl;
cout<<"Brand:\t\t"<<Brand<<endl<<"Type:\t\t"<<Type<<endl;
cout<<"Material:\t"<<Material<<endl<<"colour:\t\t"<<Colour<<endl;
}
static int getCount()
{
cout<< objectCount;
}
};
Aditionally, Borland is a really old compiler and suprised to even still
hear it's name, last release was around 15 years ago so you should really
consider using clang, gcc or msvc and upgrading your learning materials to
something less ancient. There has been alot of evolution in terms of practices,
standards and compiler conformance.
For example, C++ headers don't have an extension, and other small things like that.
This is a working version of your code:
#include <iostream>
#include <cstring>
using namespace std;
class Bag {
private:
static int objectCount;
int Weight;
string Brand, Type, Material, Colour;
public:
Bag(int W, string B, string T, string M, string C) //constructor
{
Weight = W;
Brand = B;
Type = T;
Material = M;
Colour = C;
objectCount++;
}
void print() {
cout << "\n";
cout << "Bag: \n\n";
cout << "Weight:\t\t" << Weight << "kg" << endl;
cout << "Brand:\t\t" << Brand << endl << "Type:\t\t" << Type << endl;
cout << "Material:\t" << Material << endl << "colour:\t\t" << Colour
<< endl;
}
static int getCount() //static function to count objects
{
cout << objectCount;
};
};
int Bag::objectCount = 0;
int main() {
Bag bag_1(2, "Slazanger", "Atheletic Bag", "Polyethylene", "Brown");
Bag bag_2(4, "Samsonite", "Travel Bag", "Synthetic Fibre", "Gray");
Bag bag_3(5, "Herschel", "Duffel bag", "Leather", "Black");
Bag bag_4(3, "Kewin Woods", "Hand Bag", "Fibre", "Blue");
bag_1.print();
cout << "object count" << Bag::getCount();
bag_2.print();
cout << "object count" << Bag::getCount();
bag_3.print();
cout << "object count" << Bag::getCount();
bag_4.print();
cout << "object count" << Bag::getCount();
}
There were several mistakes in the version you posted:
in C++ you don't need the .h when including files
you were using cout without the std:: qualifier or adding using namespace std; to your source. Also, please read this.
your static function was not declared/defined inside your class definition
it should be int main instead of void main
One last note: I removed your #include <conio.h> which should probably read #include <conio> and getch because I compiled this on a linux machine. Feel free to add them back in if you want them.