Using a private member function in the class - c++

So I have this class:
The purpose of this class is to change the post fix algebraic expression (1234*+-) to infix expression (1*2+3-4).
class PostfixExpression
{
private:
string postfix;
vector<string> tokenizedEx;
double result;
void tokenizeStr(); // Where do I call this?
public:
PostfixExpression(string p);
//mutators, and accessors for string and double only
//no accessor and mutator for vectors
string changeToInfix() const;
};
PostfixExpression::PostfixExpression(string p)
{
setPost(p);
}
//mutators, and accessors
void PostfixExpression::tokenizeStr()
{
stringstream ss(postfix);
tokenizedEx.clear();
string hold;
int i = 0;
while (ss >> hold)
{
tokenizedEx.push_back(hold);
}
}
//....
The purpose of the private class tokenizeStr() is to tokenizing the string and put it into the vector<string> tokenizedEx.
For example, in my main, I would have
int main()
{
PostfixExpression test("1 2 3 4 * + -");
}
Now I am trying to tokenize the string and update it to the vector<string> tokenizedEx via the private member function tokenizeStr().
After tokenized, each element in the vector should either contain an integer or an operator, but I can't seem to find a way to call the function.
I know it is totally illegal to call private member functions from main since the function is private.
Any suggestions is appreciated.

Your setPost method does what? Setting the postfix member?
You can call tokenizeStr() in the constructor, right after calling setPost.

I see a changeToInfix() method in your class which you haven't shown the implementation of. That method should be the one calling tokenizeStr().

Related

C++ Class vector error, expression must have pointer type

Currently learning some c++ and unsure why this is giving me "expression must have pointer type".
Mapp.hpp
class RouteMap
{
public:
RouteMap();
string getCurrent_();
void StoreCity(string b);
private:
std::vector<string>* cities();
string current_;
};
mapp.cpp
RouteMap::RouteMap(){}
string RouteMap::getCurrent_()
{
return current_;
}
void RouteMap::StoreCity(string b)
{
cities->push_back(b); //Error
}
std::vector<string> RouteMap::cities()
{
return std::vector<string>();
}
I am attempting to have a vector Cities as a private member so that when I run the member function StoreCity(string x), it would push_back the specific string into Cities.
I'm going to take a stab and say that the problem is cities() is a function and requires parenthesis:
cities()->push_back(b);
Edit Just found the implementation of cities() (silly me). You have another problem, and that is that your declaration and implementation don't match.
// declaration
std::vector<string>* cities();
// implementation. Notice the lack of a pointer type return
std::vector<string> RouteMap::cities()
{
return std::vector<string>();
}
It's also weird that you're returning a new vector each time. You probably want a member variable:
class RouteMap
{
//...
private:
std::vector<string> my_cities;
//...
};
and then return the member variable from there:
std::vector<string>* RouteMap::cities()
{
return &my_cities;
}
Edit2: It has come to my attention that you probably, while you could fix these things like this and get it working, the truth is that you probably don't mean for cities() to be a function at all. You probably mean for it to be a member variable instead:
class RouteMap
{
//...
private:
std::vector<string> cities;
//...
};
This requires no implementation, (aka RouteMap::cities(){}), and you can just use it inside any member function (because it's a private member) like current_.

Reference to non-static member function must be called(vector)

i have a class which named class nameAndLastname and it has a
class nameAndLastname
{
private:
vector<string> Names_Lastname();
public:
void get();
void Delete();
string search();
};
private:vector<string> Names_Lastnames(); and at first i got some names from another function and put them in vector<string> Names_Lastnames()
void nameAndLastname::get()
{
int SizeOFNames;
cout<<"enter number of the names and last names";
cin>>SizeOFNames;
vector<string> Names_Lastnames(SizeOFNames);
ifstream inFile;
ofstream outFile;
string fileName,Line;
cout<<"whats the file name?:";
cin>>fileName;
inFile.open(fileName);
getline(inFile,Line);
cout<<"the first line of the file is:"<<endl;
cout<<Line<<endl;
cout<<"outputfilename?"<<endl;
cin>>fileName;
outFile.open(fileName);
outFile<<Line<<endl;
cout<<"now enter the names and last names";
for (int i=0; i<=SizeOFNames; i++) {
getline(cin,Names_Lastnames[i]);
outFile<<Names_Lastnames[i]<<endl;
}
inFile.close();
outFile.close();
}
and now i want to delete one of the names that user want to delete and i write this
void nameAndLastname::Delete(){
string rname;
cin>>rname;
auto itr = find(Names_Lastnames.begin(), Names_Lastnames.end(), rname);
if (itr != Names_Lastnames.end()) Names_Lastnames.erase(itr);
//error~>Reference to non-static member function must be called; did you mean to call it with no arguments?
//Use of undeclared identifier 'Names_Lastnames'
}
but i have this error "Reference to non-static member function must be called" .
i want to know how can i access to my vector from class named class nameAndLastname with reference
You have declared Names_Lastnames as a function that takes no parameters and returns a vector<string>.
(You did not put anything into it - if it looks like you did, you put your names into a vector with the same name.)
Remove the parentheses to make it a vector<string>.
Like this
class nameAndLastname
{
private:
vector<string> Names_Lastname; // <--- no ()
public:
void get();
void Delete();
string search();
};
void nameAndLastname::get()
{
int SizeOFNames;
cout<<"enter number of the names and last names";
cin>>SizeOFNames;
Names_Lastname.resize(SizeOFNames); // <--- resize class vector
...
}
void nameAndLastname::Delete(){
string rname;
cin>>rname;
auto itr = find(Names_Lastname.begin(), Names_Lastname.end(), rname);
if (itr != Names_Lastname.end())
Names_Lastname.erase(itr);
}
As is common for newbies you had multiple mistakes and misunderstandings ganging up on you.
This version declares the vector (correctly without ()) in the class where all methods can access it, and resizes that vector (instead of redeclaring it) in the get method
void nameAndLastname::get()
{
//...
vector<string> Names_Lastnames(SizeOFNames);
//..
} // the scope of Names_Lastnames ends here.
It seems like, you are referring a member variable with a similar name:Names_Lastname. If yes, correct it. Then if Names_Lastname is the variable, it is declared like a function in the class body. The parenthesis is not required. Hope you will try and repost the question if required.

No members available for object declared as a class variable

I'm having a little bit of a hard time explaning the problem, so here's a simple rundown of my code:
Imagine I have a class called 'character'
#include "myEnums"
#include "weapon"
character {
protected:
string characterName;
weapon* myWeapon;
public:
string getCharacterName();
void setCharacterName( string );
string getMyWeapon();
void setMyWeapon();
}
Then within 'setMyWeapon' I use this simplified code.
void character::setMyWeapon() {
this->myWeapon = new weapon("longsword");
//this->myWeapon = new weapon(myEnums::LONGSWORD); //Ideally this
}
string getMyWeapon() {
return this->myWeapon.tostring();
}
But when I type the '.' for 'myWeapon' there's no members, anyone know whatup? Assume 'tostring' is defined in 'weapon.h'...
Since myWeapon is a pointer, you need to dereference it to access the pointee's members:
myWeapon->tostring()
// ^^^^

C++ Overloading operator +()

I have a simple class called String which has as a private field a char*.
class String {
char *s;
+ some public methods
};
I want to overload the + operator so a + b would mean that the strings from a and b are concatenated.
The function is here:
String String::operator+(String a)
{
String rez;
rez.s = new char[strlen(this->s) + strlen(a.s) + 1];
assert(rez.s);
strcpy(rez.s, this->s);
strcat(rez.s, a.s);
cout<<rez.s<<endl; // HERE rez.s CONTAINS THE RIGHT STRING!
return rez;
}
After I call this:
c = a + b;
i get an error called Debug assertion failed.
Any ideas?
First, read up on the Rule of Three
Then, consider this:
class String {
char *s; // << pointer
+ some public methods
};
"+ some public methods" better have a constructor that initializes the pointer member to a testable value (like NULL) or you're well-into undefined behavior. It better override the copy-constructor and assignment operators to properly duplicate the string from one String object to another. Finally, it better have a destructor that knows how to clean up a dynamic pointer to the content allocated in all of the above.
I strongly suggest you read that article backwards and forwards.

C++ Implementing Functions that don't utilize global declarations

My code is already working, seen here: http://pastebin.com/mekKRQkG
Right now, my functions work but utilizing information that I've declared globally, I guess, and I want to convert them so that they are in the format as seen on lines 11-15, but I'm unsure of how to convert them to do so. Simply put, I'm trying to convert my function of
"void add_county_election_file"
to be in the format of
"void add_county_election_file(const string, const vector &, const vector &, const vector &, const vector &)"
and I have no idea where to begin or how to even start.
Could someone please help me out and show me how I'd do this for the first function, so I can implement it across the board?
Thanks guys!
Your function declaration should look something like this:
void add_county_election_file(const string, vector<int>&, vector<string>..);
Make sure that your argument list for the vector template is correct(that's the type you put between <>)
Then match the implementation of you function to the declaration:
void add_county_election_file(const string, vector<int>&, vector<string>..){...}
Now call your function with apppropriate arguemtns in main:
string s;
vector<int> arg;
vector<string> sv;
void someFunction (s, arg, sv ...);
I think you are doing correct as the function you have declared
void add_county_election_file(const string, vector<int>&, vector<int>&,..);
so you just have to call the above function with the required arguments, as right now you are not passing the argument and your current definition doesn't accepts any arguments.
And as a good practice, in your int main() function you can use switch rather than going for if else.
Store your variables and functions in a class, overload operators and create functions to access these variables.
Declare all variables in int main() and set parameters to be passed into each function e.g.
void print_results() is modified to become
void print_results(std::vector<int> vec, int nCount, etc..)
Similar to the first one, create a struct to hold all data members, then pass the struct(by ref) into each function.
struct CountryTracker
{
std::vector<int> ID;
std::string name;
//etc...
}
`void print_results(CountryTracker& Obj) //pass single struct into functions`
The OOP way to do this is to create a class called perhaps ElectionInfo, where:
These would be its member fields:
vector <string> countyNameVector;
vector <int> countyNCount;
vector <int> countyFCount;
vector <int> countyOCount;
int NCount;
int FCount;
int OCount;
int NTotal;
int FTotal;
int OTotal;
and these would be its member functions:
void add_county_election_file(const string);
void search_county(const string);
void print_results();
This way you don't have to pass the references to the vectors around at all, instead you can just do:
ElectionInfo an_elect_info;
char selection = get_menu_choice();
// some if-statements to decide which of the following to call:
an_elect_info.add_county_election_file(county_name);
an_elect_info.search_county(county_name);
an_elect_info.print_results();
But if you'd prefer to stay with the current functional approach:
Declare and initialize the following inside your main method:
vector <string> countyNameVector;
vector <int> countyNCount;
vector <int> countyFCount;
vector <int> countyOCount;
int NCount;
int FCount;
int OCount;
int NTotal;
int FTotal;
int OTotal;
The syntax for the commented out function declarations should be tweaked to look like this:
void add_county_election_file(const string, vector<string>&, vector<int>&, vector<int&, vector<int>&);
(Of course, the definition should follow suit)
You would invoke it like this:
add_county_election_file(countyname, countyNameVector, countyNCount, countyFCount, countyOCount);
Objects are automatically passed-by-reference.
The basic process of refactoring should at the first step involve only code grouping and placement and should only minimally involve writing new logic. Using this as a principle you can go about modifying the code in the following way at first.
string ReadInputString(const char* title)
{
string s
cout << title;
cin >> s;
}
void add_county_election_file(const std::string& filename
, std::vector<string>& countyNameVector
, std::vector<int>& countyNCount
, std::vector<int>& countyFCount
, std::vector<int>& countyOCount
)
{
int NCount = 0;
int FCount = 0;
int OCount = 0;
int NTotal = 0;
int FTotal = 0;
int OTotal = 0;
char vote;
std::ifstream input((filename).c_str());
string countyName;
if(input.is_open())
{
input >> countyName;
countyNameVector.push_back(countyName);
while(input >> vote)
{
if(vote == 'N' || vote == 'n')
{
NCount = NCount + 1;
}
else if(vote == 'F' || vote == 'f')
{
FCount = FCount + 1;
}
else
{
OCount = OCount + 1;
}
}
countyNCount.push_back(NCount);
countyFCount.push_back(FCount);
countyOCount.push_back(OCount);
}
cout << countyName << endl;
}
void add_county_election_file()
{
string fn = ReadInputString("Enter the county file to process: ");
add_county_election_file(fn,g_countyNameVector,g_countyNCount,g_countyFCount,g_countyOCount);
}
As you can see I have just extracted your code and moved them to individual functions and changed names to make some significance. Like in the function ReadInputString - the line "cin >> s" was originally "cin >> filename". The abstract name "s" is to signify that the ReadInputString has no knowledge or doesn't care what the semantic meaning of the string it is reading from console.
In order to not change your main function - I have added a overloaded add_county_election_file that calls one function followed by another. The idea is that you should keep something unchanged and change others (for good) and then alternate if need be.
And I have changed names of your global variable to differentiate them from the local variable using "g_" - the point is that "g_" should only be found at very few places in your code.