Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Thanks so much for taking the time to look at my question!
Right now I am working with classes and objects. I am trying to write a program that stores information about visitors to a hotel. A user will input the name of the visitor and some information about them. The program will then store that information in an object and be able to calculate how much to charge for the users stay.
The problem that I am running into is that I don't know how to let the program create new objects for the visitors. For example, if Sally came in I would like to create a new object for her within the program that could store her information.
I have looked at dynamic object creation and done a fair amount of Googling on the subject but can't seem to find any answers. Here is a simplified version of what I would like to do:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class visitor {
public:
string name;
int age;
};
int main()
{
//a new person comes to the hotel, the person at the desk gives the program his/her name
//and age and it is put into a class so it can be used later.
}
If there is a better way to accomplish this I would love suggestions, I am but a fledgling programmer and it is very possible that I am approaching this incorrectly.
Thanks in advance!
You have done fine, so far.
class visitor {
public:
string name;
int age;
};
int main()
{
//a new person comes to the hotel, the person at the desk
//gives the program his/her name
//and age and it is put into a class so it can be used later.
}
Now remember how easy it is to define a integer value i, and initialize it with 0:
int i = 0;
Your class is just like "int". So name a variable declared just like int.
visitor guest1;
You should write a default ctor to initialize the contents. Note that your code has a default ctor provided by the compiler. But what it does (nothing) is not terribly useful.
And then write a non-default ctor to fill in the contents.
and so on, and so on.
How about a show method to display values.
guest1.show();
Good luck.
You need to create a constructor. This is a function that constructs visitors. We write that as follows:
class Visitor {
public:
string name;
int age;
Visitor(string name, int age) {
this->name = name;
this->age = age;
}
};
We can then create a new Visitor object (note that its usual convention to make a class name's first letter uppercase) with the following:
Visitor sally = Visitor("Sally", 22);
To allow the user to input what we want the name and age to be, you should look at another SO answer like Getting user input in C++.
EDIT: You don't need to create a constructor as the compiler will make one by default in this case, but it will be useful for you to learn by creating your own constructors for the time being, so you know what's happening.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Some backstory...
For a homework assignment in my Data struct and algorithms,(early on) I have to create a class definition and implementation that models a store item, formatted with Part number, department code, and price. I have it mostly done except for one constructor overload that I can't seem to figure out how to start. Sample of what I have so far.
/** Default Construct*/
Item() : Part_Num("------"), Dep_Code("---"), item_Price(0){}
/** First 3Param Constructor*/
Item(std::string partNum, std::string dept, std::string priceStr):
Part_Num(partNum),Dep_Code(dept), item_Price(stod(priceStr)){}
/** Second 3Param Constructor*/
Item(std::string partNum, std::string dept, double priceD) :
Part_Num(partNum), Dep_Code(dept), item_Price(priceD) {}
The issue I have, is that I need to create a one parameter constructor that takes a string, in the format of
BN3782 ELE 87.25
and splits it into the correct data members. I have an idea for the parsing, but I don't know how to define the constructor to start. Just a push in the right direction would be appreciated. This is my first post and I'm not great at explaining, so let me know if anyone needs any additional information.
I have tried
Item(std::string data) : Part_Num(data), Dep_Code(data), item_Price(data){}
But that has yet to work with my code, and I'm not sure why it would... (was suggested on another forum).
EDIT: I got it working with pm100 suggestion, Here's a code sample I got working for anyone in the future having the same problem.
Item(std::string line) {
item_Data = line;
line = removeSpaces(item_Data);
Part_Num = line.substr(0, 6);
Dep_Code = line.substr(6, 3);
item_Price = stod(line.substr(9));
}
You need to code the field assignments
Item(std::string &valstr)
{
Part_Num = <parsed bit of string>;
Dep_Code = <a different part of the string>;
}
For the sake of completeness, if you like you can still use the initilizer list. You just need to do the parsing somewhere. Lets say you have a:
std::string nth_part(int n,std::string s) { ... }
Then your constructor could be
Item(std::string s) :
Part_Num(nth_part(0,s)), Dep_Code(nth_part(1,s)), item_Price(nth_part(2,s)) {}
However, this would require you to process the string 3 times (which you dont need if you do it in the constructor body). Using the initializer list is good practise, but not always it really pays off.
Item(std::string data)
{
int i=0;
int counter=0;
std::string temp="";
int len=data.length();
while(i<len)
{
if(data[i]!=' ' && i<len-1)
{
temp+=data[i];
}
else
{
if(counter==0) Part_Num=temp;
else if(counter==1) Dep_Code=temp;
else
{
temp+=data[i];
item_price=stod(temp);
}
++counter;
temp="";
}
++i;
}
}
this will give you the desired result for your problem, you can check it by running.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
lets assume I have a number instance of a class vehicle instantiated. if the vehicle object wants to query other existing vehicles for some reason ( for example finding the nearest vehicle), should the class manages the instantiated objects through static members and methods as in the code below? is this a good design pattern? is this a common standard? is there any pitfall if i take this approach?
#include <vector>
#include<algorithm>
struct Location {
double x, y, z;
Location(double xx, double yy, double zz) : x(xx), y(yy), z(zz) {}
};
class Vehicle {
private:
Location l;
public:
Vehicle (Location ll) : l(ll) {
vv.push_back(this);
}
static std::vector<Vehicle*> vv;
~Vehicle() {
std::vector<Vehicle*>::iterator it;
// removing the Vehicle object from the list of existing vehicles
for (it = vv.begin(); it != vv.end(); it++){
if (*it == this) {
vv.erase(std::remove(vv.begin(), vv.end(), this), vv.end());
}
}
}
Vehicle& find_nearest_vehicle () {
// code to iterate through list of existing vehicles and find the nearest vehicle
}
};
static std::vector<Vehicle*> vv;
Put it into any of the typical OO scenarios used as examples:
Does an animal know about every other animal?
Does a car know about every other car?
Does a color know about every other color?
What you are asking is really opinion based, but I'm sure most people would say "no". You use some kind of manager class to control the instances.
In your case I'd have a Vehicle which knows it's location and a VehicleManager which knows about all the Vehicles. If you want to know what color a Vehicle is you ask the Vehicle. If you want to know where all the Red Vehicles are - you ask the VehicleManager.
Your solution has a combined Vehicle/VehicleManager which relies on a static collection of vehicles so you can only ever have one set. If you use two classes as I've described you can have multiple sets. e.g. Vehicles of different companies or trucks vs cars etc - sure there are other ways to do this as well, but your solution locks you in. Using 2 classes is much more flexible.
So to answer your last comment: do you think it's ok or is it a terrible design? - It is terrible design.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Current state of my solution
#include <iostream>
class money {
int kn, lp;
public:
void add(int kn, int lp){
this->kn+=kn;
this->lp+=lp;
if(this->lp>=100){
this->kn++;
this->lp-=100;}
}
void print() {
std::cout<<this->kn<<" kuna";
if(this->lp!=0) std::cout<<", "<<this->lp<<" lipa";
}
};
int main () {
//money a(7, 50) , b(3, 70) , c(2, 80);
money a;
//simplified
a.add(3, 70);
a.add(2, 80);
a.print();
}
Task requires me to expand the class, so that the below program correctly adds the money and prints it. http://prntscr.com/711bs5
I simplified the task, because I'm still getting to the final solution. But I don't know why does it print garbage? And after I solve that.
Can someone help me in short tips, what's needed to correctly solve the task. Obviously when I'm instancing those objects, I'm supposed to add to object a, the values from objects b and c. But I don't know how to do that, I missed a few lessons.
EDIT: Why do people downvote? Am I missing something? Too trivial question? Bad title?
For the first part: initialize.
For the second part you have to create a method taking another instance of class money as a parameter and add the values of kn and ln to the ones of the existing.
#karma:
It's not a formula, but there is no check how money values have to be entered.
The smartest thing in my opinion would be to check the correct behavior while instancing an object (in the constructor), so that objects can only be of form:
0<=lp<=99;
edit2:
How do you create this method?
For ones, since your add method already exists you can OVERLOAD it. This means you create a method with the same name and return type, but having different parameters.
So you can create another method add and pass a money instance to it, as already mentioned. If you don't understand that, you should really have a look at how methods work and how to create them and that basically anything can be passed to them (not just primitive types).
You need to initialize the variables before you use them.
When you use variables without initializing them, you get garbage values. For instance, here:
this->kn+=kn;
this->lp+=lp;
both of them are uninitialized.
For data members of a class, you can initialize using a constructor as follows:
money()
{
kn=0; lp=0;
}
So, your code now becomes:
#include <iostream>
class money {
int kn, lp;
public:
money()
{
kn=0; lp=0;
}
void add(int kn, int lp){
this->kn+=kn;
this->lp+=lp;
if(this->lp>=100){
this->kn += this->lp/100; this->lp %= 100;}
}
void print() {
std::cout<<this->kn<<" kuna";
if(this->lp!=0) std::cout<<", "<<this->lp<<" lipa";
}
};
int main () {
//money a(7, 50) , b(3, 70) , c(2, 80);
money a;
//simplified
a.add(3, 70);
a.add(2, 80);
a.print();
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
First of all, I have been looking on stackoverflow for more than 1 hour, but I really don't know, how to find the specific question I'm looking for (I guess there is already some answer).
I am trying to call an object via variable (string)
example of my code:
//class itself
using namespace std
class locations {
public:
locations(int id, string name){ // constructor
this->id= id;
this->name=name;
}
int id= 0;
string name = "";
};
and new object:
locations home(1,"home");
what I want now is something like:
string obj = "home";
obj.id = 3;
or
string meth = "id";
home.meth = 3;
If you have any good links to other questions it would be helpful.
Maybe it can be accessed somehow through vectors but I don't know about it a lot
C++ is designed with strong typing and compile time checking and optimization in mind. There's no build in facilities for the kind of access that you desire.
1) Find dynamically an object:
C++ doesn't support the semantic that you expect:
string obj = "home"; // create an object of type string.
obj.id = 3; // access to member id of your object.
If it would be dynamic, the generated code would need to maintain the scope of variables (because the home object can have different meansings in different scope.
But fortunately you can easily implement an object store, in wich you register your objects and their name, with the help of a map :
map<string, locations> mystore; // store of all my location variables
mystore["home"] = locations(1,"home"); // copy a new object into the store
string obj = "home";
mystore[obj].id = 3; // access object via its name.
By the way, if locations::name is only there to give access by name, you'd no longer need it in locations, as the map links the string to the object value anyway.
2) Find dynamically a member:
C++ doesn't support your semantic at all:
string meth = "id"; // name of a member
home.meth = 3; // invalid: because meth is not a member of home
C++ doesn't support reflection that you find in java and other semi-compiled or interpreted languages. If you need something like that, you'd need to design carefully your classes to implement this by yourself. It'll be rather difficult as every member can have its own type, and C++ needs to know the type at compile time.
One way would be to combine the use of a map (to store your dynamic members) with the use of boost::variant (to store in the map objects that can have different type of values).
But it's not easy, and most of all, you'd have to manage by yourself any inheritance logic betwwen diferent classes.
This isn't how thing are done in C++, C++ is a object oriented, statically typed, value semantics language. All of these affect design, and the design you seem want just don't fit with a statically typed language. Whether this lead you to change design, or change language is up to you. That said, if you really want to map objects and methods runtime, it could be emulated something like this:
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct Object;
typedef int (*funcptr)(Object*,int);
struct Object
{
map<string,funcptr> funcs;
map<string,int> data;
int call(string name,int param) { return funcs[name](this,param); }
};
map<string,Object> allObjects;
Object& get(string name) { return allObjects[name]; }
//----------------------------------------------------------------------------------
int main()
{
get("obj1").funcs["run"] = [](Object* self,int param) -> int { self->data["somename"] = param; return 0; };
get("obj1").call("run",5);
cout << get("obj1").data["somename"] << endl;
}
That said, please don't do that, change your design to something that actually is a good fit for C++'s strengths, i.e. object oriented, statically typed, value semantics.
Hello to all that read
I am self learning C++ from a text book.
...and I have been given a serious of questions that I am have trouble interpreting, the questions are:
4.
Modify the constructor of Exercise 3 so that it assigns a new ID number as each variable is established. The ID number should be output to the screen.
**Please Note: Exercise 3 was just adding a Class constructor to the class structure - and basically setting all the class private member variables to '0' within that added constructor.
5.
Add constructors to the class of exercise 4. They should output the ID number when they are invoked.
6.
Write a constructor whose argument is an ID number. Overload it with the constructor of(Exercise 5) and then Write a main program to test this new constructor.
**So the questions: 4 and 5 are confusing me as they appear to be asking the same questions (i.e outputting the I.D numbers) and I need more than one 'constructor' in order to do this( I get that part).
**Question 6 Is effectively asking me to overload more than one instance declared of the class with an ID number as the argument!!!! I am confused because in my text book it specifically states that you cannot have an argument for a constructor when you have an array of classes declared within in the main program.
So if anyone can shed light on these questions and clarify how they would proceed I would appreciate the help. I appreciate that I may of interpreted the questions wrongly that is why I am asking for help.
**Please note: The name of the class: 'class classroom' is not ideal but it is what I copied from the text book question!
**Please also note that I have answered (I think!) exercise/question 4 by adding code that Id's each instance of the class variable.
And the relevant code relating to the above questions are:
#include <iostream>
#include <cstdio>
using namespace std;
class classroom{
char name[25];
int student_id;
float grades[10];
float average;
int num_tests;
float letter_grade;
**static int next_student_id;**
public:
void enter_name_id(void);
void enter_grade(void);
void average_grades(void);
void letter_grades(void);
void output_name_id_grade(void);
classroom();
};
**int classroom::next_student_id=1;**
and the constructor:
classroom::classroom(){
int i;
num_tests=0;
**student_id=next_student_id++;**
**cout<<"\nstudent id: "<<student_id;**
average=0.0;
for(i=0;i<10;i++){
grades[i]=0.0;
}
for(i=0;i<27;i++){
name[i]='-';
}
cout<<"\n*****************Finished*****************";
}
And the main program declaration:
int main()
{
classroom students[3];
//and so on...
}
and the code added for question/Exercise 4 was:
in the class structure I added the following private member variable:
**static int next_student_id;**
and outside of the class structure I initialized the static variable to 1
int classroom::next_student_id=1;
and in the constructor I added this code: which basically outputted to the screen a unique ID for each instance of classroom class variable:
student_id=next_student_id++;
** cout<<"\nstudent id: "<
Many thanks in advance
Questions 4 and 5 do appear to be the same from what you've provided - I'd reread it carefully to be sure, but it wouldn't be the first time textbook examples had a typo (in fact, I've run across that many times - alot of book companies are lazy when it comes to the exercises).
You do have the right answer with your static counter, so I wouldn't worry about it - you've understood the goal and solved the problem.
Question 6... it sounds like it wants you to just add an extra constructor to the class - so, you would have the default constructor (which you must explicitly write, but you already have done this in order to do your static counter), and you would also have a one-parameter constructor taking an integer. The one-parameter constructor should not need to use the static variable as it is allowing the user to provide the id to the class explicitly.
Moving on (since I think you've already got all of this), you are also correct in thinking that you can't provide an argument to a constructor when making an array. To test #6 as it suggests, you'll either have to make a stand-alone object (i.e. not an array), or something like a std::vector or other container that provides this capability.
#include <iostream>
#include <vector>
class A {
public:
A(int i) { /* Empty */ }
};
int main()
{
//Creates a new vector holding 5 A's initialized with the 2nd parameter.
std::vector<A> myVec(5, A(7));
}
Note that this technically creates a temporary A which is used to initialize the 5 vector entries. Also note that a std::vector is part of the STL (standard library), and it is basically a dynamically sized array.
Where, point 6, requires to have an array of class objects?
int main()
{
classroom studentA(100);
classroom studentB();
classroom studentC(200);
classroom studentD();
classroom students[100];
//and so on...
}