I am in a situation that I need to make objects in runtime that are named by value of a string, but I can't do that:
cin>>input;
className "input"= new className;
How can I do that?
I think it is possible to achieve by using maps. Is it true?
As you said, you can achieve your goal by using std::map (or std::unordered_map)
map<string, className*> aMap;//map a string to a className pointer/address
cin>>input;
aMap[input] = new className; //input is mapped to a className pointer
Then you can treat aMap[input] as a className*. e.g.
To call a className method, you can:
aMap[input]->aClassNameMethod();
The object oriented way would be to make name a member of that class and use the input to construct the class.
#include <string>
#include <iostream>
class Foo
{
std::string myName;
public:
// Constructor assigning name to myName.
Foo(const std::string name) : myName(name) {}
std::string GetMyName() const
{
return myName;
}
};
int main()
{
std::string input;
std::cin >> input;
Foo f(input);
std::cout << f.GetMyName();
}
Also read about new in C++: Why should C++ programmers minimize use of 'new'?
Related
So my goal is to pass this vector vector 'Beer' allBeers to a function UnitedStatesBeer::getBeerTop(), but when I try to do that, I get the error that there's too many arguments in function call, or my object is not initialized.
How do I fix this? Thanks for your help!
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
class RatingCalculator
{
public:
virtual void showCountryTop() = 0;
virtual void getCountryTop() {};
};
class Beer
{
public:
string name;
string rating;
string country;
string alc;
string type;
};
class UnitedStatesBeer : public RatingCalculator
{
private:
string name;
string rating;
string country;
string alc;
string type;
public:
void showCountryTop() {};
void getCountryTop(vector<Beer> allBeers){};
int main()
{
ifstream file("beer.txt");
Beer currentBeer;
vector<Beer> allBeers;
for (int i = 0; !file.eof(); i++)
{
getline(file, currentBeer.name, '\t');
getline(file, currentBeer.rating, '\t');
getline(file, currentBeer.country, '\t');
getline(file, currentBeer.alc, '\t');
getline(file, currentBeer.type, '\n');
allBeers.push_back(currentBeer); //copy all the information to allBeers vector
}
file.close();
/*if I do it this way*/
UnitedStatesBeer UsReassign;
UsReassign->getCountryTop(allBeers); //<- expression (UsReassign) must have pointer type/ Using uninitialized memory
// RatingCalculator* UsReassign = new UnitedStatesBeer();
// UsReassign-> getCountryTop(allBeers); //<- too many arguments in function call
}
First off, Since you want to override virtual function, you'd want to match function definition in Base Class aka RatingCalculator with the one in UnitedStatesBeer. This is how it should look in RatingCalculator :
virtual void getCountryTop(vector<Beer> allBeers) {};
and in UnitedStatesBeer
void getCountryTop(vector<Beer> allBeers){};
Secondly, since you want to get Top beers, you may want to pass by reference, by adding & in front of variable beers.
Thirdly,
UsReassign->getCountryTop(allBeers); //<- expression (UsReassign) must have pointer type/ Using uninitialized memory..
This is happening because UsReassign is a object and NOT a pointer. Objects are referenced with . instead of ->.
And Lastly,
// UsReassign-> getCountryTop(allBeers); //<- too many arguments in function call
This is happening because function getCountryTop() with NO arguments is being called. Steps mentioned in "Firstly" should fix it.
I just started learning about vectors, and they seem really handy, if talking about lists from a file. But I'm having a problem while trying to return a new vector from a class method and put it to another method of the same class.
i.e.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
class A
{
public:
string name;
string age;
};
class Test
{
string name;
string age;
public:
void get(vector<A> students)
{
vector<A> specificStudents;
//rewrite a couple of students from vector<A>students
//to vector<A> specificStudents
};
void set(vector<A> specificStudents)
{
//I need to get vector<A> specificStudents here
};
};
int main()
{
vector<A> students;
A stud;
ifstream file("file.txt");
for (int i = 0; i < file.eof(); i++)
{
getline(file, stud.name);
getline(file, stud.age);
students.push_back(stud);
};
Test test;
test.get(students);
return 0;
}
Can I return it as a function argument?
It is not entirely clear, but do you want to save a copy of students inside test?:
class Test
{
vector<A> specificStudents;
public:
const vector<A>& get() const
{
return specificStudents;
}
void set(const vector<A>& students)
{
specificStudents = students;
// maybe modify `specificStudents` here in some way or assign it differently
}
};
int main()
{
vector<A> students;
A stud;
ifstream file("file.txt");
while (getline(file, stud.name) && getline(file, stud.age))
{
students.push_back(stud);
}
Test test;
test.set(students);
//... Do something with test
return 0;
}
If you don't know yet what & and const mean in this, you can just remove them (until you learn about them).
You seem to have gotten get and set mixed up. By usual convention, get gets something stored in the class object to the caller and set sets something in the class object (with a value provided by the caller).
I also fixed your input loop. I don't know what you thought file.eof() does, but comparing to i does not do anything useful.
Also be aware of where ; belongs and where it doesn't. It belongs after single statements and class definitions, but not after } of function definitions or other statement blocks, such as the one of while.
YES, you can return vector from a function.
To do this you can write a function like this one:
std::vector<A> get(vector<A> students)
and the inside it return the vector. An example can be:
vector<A> get(vector<A> students)
{
vector<A> specificStudents;
//rewrite a couple of students from vector<A>students
//to vector<A> specificStudents
return specificStudents;
};
I have created an array dynamically of structures and now i am willing to pass it to function.What is the correct method of doing it?What should i put in parameter of function in MAIN for doing it?
void function(Data *family)
{
//code
}
int main()
{
struct Data{
string name;
int age;
string dob;
};
Data *family = new Data[3];
function(Data); //ERROR in parameter i guess!
}
It is better to use more safe ways using std::vector or std::shared_ptr. Because it is easy to make a mistake when you use raw pointers.
If you really need to use raw pointer than you need fix your code:
#include <string>
#include <iostream>
// "Data" should be declared before declaration of "function" where "Data" is used as parameter
struct Data {
std::string name;
int age;
std::string dob;
};
void function(Data *family)
{
std::cout << "function called\n";
}
int main()
{
Data *family = new Data[3];
// fill all variables of array by valid data
function(family); // Pass variable "family" but not a type "Data"
delete[] family; // DON'T FORGET TO FREE RESOURCES
return 0; // Return a code to operating system according to program state
}
Every c++ programmer needs to learn std::vector, which is a dynamic array:
#include <vector>
struct Data{
string name;
int age;
string dob;
};
void function(const std::vector<Data>& family)
{
//code
}
int main()
{
auto family = std::vector<Data>(3);//family now contains 3 default constructed Data
function(family);
}
Not sure what actually what actually you are looking for, I guess you can try like this:
First define your structure outside from main so it would be accessible as function parameter. Then instead of Data pass object family to the function.
struct Data {
string name;
int age;
string dob;
};
void function(Data *family)
{
//code
}
int main()
{
Data *family = new Data[3];
function(family);
}
I'm currently defining a few properties for a class in C++ but I'm running into trouble when using type string as opposed to something like int or double. For example:
private:
int LOT;
public:
int getLOT() {
return LOT;
}
void setLOT(int value) {
LOT = value;
}
works fine, but:
private:
string name;
public:
string getName() {
return name;
}
void setName(string value) {
name = value;
}
throws these errors:
https://s26.postimg.org/wm5y7922h/error.png
The file (a header) looks something like this:
#include "general.h" // a header which includes all my other #includes
// which, yes, does include <string>
class MyClass
{
private:
string name;
public:
string getName() {
return name;
}
void setName(string value) {
name = value;
}
// other properties similar to the above
}
The purpose is to access the variable like this:
cout << "Enter your name: ";
cin >> MyClass.setName();
cout << "\nHello, " << MyClass.getName();
// although this isn't exactly how it'll be used in-program
If anyone could provide help with what I'm doing wrong or a better way to go about a string property (as, like I mentioned before, other types work fine) it would be greatly appreciated. Thanks.
string is part of std namespace.
You must use std::string instead of string or add using namespace std; (what I would not recommend you to do in your header file, read "using namespace" in c++ headers).
I'm having trouble declaring and initializing a char array. It always displays random characters. I created a smaller bit of code to show what I'm trying in my larger program:
class test
{
private:
char name[40];
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test()
{
char name [] = "Standard";
}
int main()
{ test *test1 = new test;
test1->display();
}
And sorry if my formatting is bad, I can barely figure out this website let alone how to fix my code :(
If there are no particular reasons to not use std::string, do use std::string.
But if you really need to initialize that character array member, then:
#include <assert.h>
#include <iostream>
#include <string.h>
using namespace std;
class test
{
private:
char name[40];
int x;
public:
test();
void display() const
{
std::cout<<name<<std::endl;
}
};
test::test()
{
static char const nameData[] = "Standard";
assert( strlen( nameData ) < sizeof( name ) );
strcpy( name, nameData );
}
int main()
{
test().display();
}
Your constructor is not setting the member variable name, it's declaring a local variable. Once the local variable goes out of scope at the end of the constructor, it disappears. Meanwhile the member variable still isn't initialized and is filled with random garbage.
If you're going to use old-fashioned character arrays you'll also need to use an old-fashioned function like strcpy to copy into the member variable. If all you want to do is set it to an empty string you can initialize it with name[0] = 0.
Since you are using C++, I suggest using strings instead of char arrays. Otherwise you'd need to employ strcpy (or friends).
Also, you forgot to delete the test1 instance.
#include <iostream>
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
}
};
test::test()
{
name = "Standard";
}
int main()
{
test test1;
test1.display();
std::cin>>x;
}
Considering you tagged the question as C++, you should use std::string:
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test() : name("Standard")
{
}
c++11 actually provides two ways of doing this. You can default the member on it's declaration line or you can use the constructor initialization list.
Example of declaration line initialization:
class test1 {
char name[40] = "Standard";
public:
void display() { cout << name << endl; }
};
Example of constructor initialization:
class test2 {
char name[40];
public:
test2() : name("Standard") {};
void display() { cout << name << endl; }
};
You can see a live example of both of these here: http://ideone.com/zC8We9
My personal preference is to use the declaration line initialization because:
Where no other variables must be constructed this allows the generated default constructor to be used
Where multiple constructors are required this allows the variable to be initialized in only one place rather than in all the constructor initialization lists
Having said all this, using a char[] may be considered damaging as the generated default assignment operator, and copy/move constructors won't work. This can be solved by:
Making the member const
Using a char* (this won't work if the member will hold anything but a literal string)
In the general case std::string should be preferred