#include<iostream>
#include <string>
using namespace std;
class Car{
private:
public: Car(int, string, int);
Car(){} //default constructor
void setbrake();
void setacc();
int year,speed;
string make;
};
Car::Car(int year, string make, int speed = 0) //constructor with parameters
{
cout << "Enter your car's year." << endl;
cin >> year;
cout << "Enter your car's make. " << endl;
cin >> make;
cin.ignore();
speed = 0; }
void Car::setbrake(){ //first function
speed = speed - 5;
cout << "Your " << make << " is traveling at " << speed;
cout << " MPH.";}
void Car::setacc(){ //second function
speed = speed + 5;
cout << "Your " << make << " is traveling at " << speed;
cout << " MPH.";}
int main()
{
Car car1(0,"s");
cout << car1.make;
cout << car1.speed;
cout << car1.year;
car1.setacc();
system("pause");
return 0;
}
I'm having a problem getting my variables to display in my two member functions, and it doesn't display anything in main.
The speed variable always comes out to 49898575 <-- some randomly high number like that, and I assume I initialized it to 0.
I've been stuck on this all week.
How do I connect my class private variables and my member functions.
I thought my constructor with parameters would take care of that problem, but obviously not.
Can someone please take the time to critique this code for me. I'm going to pull my hair out.
Here's the problem that was assigned for class, and this is what I'm aiming to do, but I'm not catching on to classes and member functions, and how they work together.
Write a class named Car that has the following member variables:
• year. An int that holds the car’s model year.
• make. A string that holds the make of the car.
• speed. An int that holds the car’s current speed.
In addition, the class should have the following member functions.
• Constructor. The constructor should accept the car’s year and make as arguments
and assign these values to the object’s year and make member variables. The constructor
should initialize the speed member variable to 0.
• Accessors. Appropriate accessor functions should be created to allow values to be
retrieved from an object’s year, make, and speed member variables.
• accelerate. The accelerate function should add 5 to the speed member variable
each time it is called.
• brake. The brake function should subtract 5 from the speed member variable each
time it is called.
Demonstrate the class in a program that creates a Car object, and then calls the accelerate
function five times. After each call to the accelerate function, get the current speed of the car and display it.
Then, call the brake function five times.
After each call to the brake
function, get the current speed of the car and display it.
You're changing the values of your parameters, which shadow your members, leaving both ints uninitialized (the string will be an empty string).
The better option is to use different names:
Car::Car(int y, string m, int s = 0)
You could, however, use this:
this->speed = 0;
I'd recommend a constructor initializer list, though, which doesn't require either, and doing it in the order they're declared in the class:
Car::Car(int year, string make, int speed = 0)
: year(year), speed(speed), make(make) {}
Ideally, I would do something like this, with tweaking depending on what else it's meant to be used for (I'll keep it C++03):
class Car {
int year_;
std::string make_;
int speed_;
public:
Car(int, const std::string &, int);
void brake();
void accelerate();
void printInfo() const;
};
Car::Car(int year, const std::string &make)
: year_(year), make_(make), speed_() {} //speed should always be 0
void Car::brake() {
speed_ -= 5; //consider ensuring it stays at or above 0
}
void Car::accelerate() {
speed_ += 5;
}
void Car::printInfo() const {
std::cout << "Your " << make_ << " is traveling at " << speed_ << " MPH.";
}
You'll have to figure out exactly what the default constructor should do if you want one. I used a constructor initializer list to initialize the data members, I separated the printing from the accelerating/braking, accepted const references where reasonable, and made the printing function const since it doesn't modify the object.
Related
I have got a question -
Write a c++ program to calculate Gross salary(net salary+DA+TDS) for 4 employees where overload the + operator for getting the total salary obtained by all the 4 employees. Also get the average salary of employees by operator overloading. display all the details of all four employees. Also display who is getting highest salary. Employee salary must be entered by the user at runtime.
#include<iostream>
#include<string>
using namespace std;
class Employee
{
private:
int net_salary, DA, TDA, Gross_salary;
public:
void SetData(int net, int da, int tda, int gross)
{
net_salary=net;
DA=da;
TDA=tda;
Gross_salary=gross;
}
void GetData()
{
cout << "Enter net salary: "<<net_salary;
DA = (15*net_salary)/100; //Declaring the value of DA as 15% and calculating the amount
//on basis of net salary of the employee
TDA = (10*net_salary)/100; //Declaring the value of TDA as 10% and calculating the amount
// of TDA on basis of net salary
Gross_salary = net_salary+DA+TDA;
}
void DisplayData()
{
cout << "Total Gross Salary = "<<Gross_salary;
}
Employee operator +(Employee e)
{
Employee temp;
temp.Gross_salary=Gross_salary+e.Gross_salary;
return temp;
}
};
int main()
{
Employee e1,e2,e3,e4,e5;
e1.GetData();
e2.GetData();
e3.GetData();
e4.GetData();
e5=e1+e2+e3+e4;
e5.DisplayData();
return 0;
}
The trouble comes from the absent initial values for the data members.
// ...
cout << "Enter net salary: " << net_salary;
DA = (15*net_salary)/100;
// ...
Here, in the GetData() member function, that is called after you have created five default initialized objects e1,e2,e3,e4,e5 of Employee type. The net_salary here is of built-in type and is default initialized by the implicitly defined default constructor, hence it has an undefined value. Then you assign this undefined value to the DA and so on in the body of the GetData().
You should not look toward the SetData() as a solution for this, since it should act as a setter method, a method used to modify an already initialized object. You will need to implement constructor(s) for your class, or you can at least supply in-class initializers for the members, like so:
// ...
int net_salary=0, DA=0, TDA=0, Gross_salary=0;
// ...
I can't help but notice that GetData() either has a confusing name or tries to do more than it is intended to do. It does some internal computation, which is ok for a GetSomething function, but it modifies internal data while does some prints.
Also, note the line (in the GetData()):
Enter net salary:
Will be followed by an output, you won't be given a chance to input any data in the GetData(). I assume, you may want to create a constructor that takes input from a user, and then call a function to do all the needed computations.
I am new to classes and constructors. This program requires user to input name for two circles. I defined a default constructor to set parameters for radius and name and another constructor to accept them as arguments. I believe there is an issue with setName and also it tells me the constructors have already been defined. Any help is appreciated!
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
class Circle
{
private:
double pi = 3.14;
double radius;
string *name;
public:
Circle();
Circle(double, string);
Circle::Circle()
{
radius = 0.0;
*name = nullptr;
}
Circle::Circle(double r, string n)
{
radius = r;
*name = n;
}
~Circle()
{
delete[] name;
}
void setRadius(double r)
{
if (r >= 0)
radius = r;
else
{
cout << "Invalid radius\n";
exit(EXIT_FAILURE);
}
}
double getRadius()
{
return radius;
}
double getArea()
{
return pi* radius * radius;
}
double getCircumference()
{
return 2 * pi * radius;
}
void setName(string n)
{
*name = n;
}
string getName()
{
return *name;
}
};
int main()
{
Circle circle1;
Circle circle2;
double circRad1;
double circRad2;
string name1;
string name2;
cout << "Enter the name for circle 1: ";
getline(cin, name1);
cout << "Enter the name for circle 2: ";
getline(cin, name2);
cout << "Enter the radius for cirle 1: ";
cin >> circRad1;
cout << "Enter the radius for cirle 2: ";
cin >> circRad2;
circle1.setRadius(circRad1);
circle2.setRadius(circRad2);
circle1.setName(name1);
circle2.setName(name2);
cout << "Circle 1 name: " << circle1.getName() << "\n";
cout << "Circle 1 radius: " << circle1.getRadius() << "\n";
cout << "Circle 1 area: " << circle1.getArea() << "\n";
cout << "Circle 1 circumfrence: " << circle1.getCircumference() << "\n";
cout << "\n";
cout << "Circle 2 name: " << circle2.getName() << "\n";
cout << "Circle 2 radius: " << circle2.getRadius() << "\n";
cout << "Circle 2 area: " << circle2.getArea() << "\n";
cout << "Circle 2 circumfrence: " << circle2.getCircumference() << "\n";
return 0;
}
Problems I see:
Constructors
You have:
Circle();
Circle(double, string);
Circle::Circle()
{
radius = 0.0;
*name = nullptr;
}
Circle::Circle(double r, string n)
{
radius = r;
*name = n;
}
That is not correct since the first two lines declare the constructors while you declare, and define, them again with incorrect syntax.
Remove the first two lines.
Use of name
It's not clear why you are using string* for name. Make it an object, not a pointer.
string name;
Then, change the constructors to:
// Use the default constructor to initialize name
Circle() : radius(0.0) {}
Circle(double r, string n) : radius(r), name(n) {}
You may remove the destructor altogether. If you insist on having one, change it to (there is no need for delete name any more):
~Circle() {}
Change setName() to:
void setName(string n)
{
name = n;
}
Change getName() to:
string getName() const
{
return name;
}
PS Your attempted code indicates to me that you will benefit from going through the fundamentals of the language from a good book. See The Definitive C++ Book Guide and List for ideas.
I just want to add to the previous answer since I don't have enough points to comment.
In his constructor, he's using what's called an initializer list:
i.e.
Circle() {
foo = 0;
bar = 0;
}
versus (initializer list):
Circle() : foo(0), bar(0) {}
When you're just initializing variables, the preferred practice is almost always the list format. This is because it provides the arguments to construct your object before it is instantiated. This would allow you to construct objects whose "identity" isn't known until runtime (i.e. a variable-type object, or an object which could take on more than one type, although these aren't quite native to c++), or a const value.
I am a little suspicious about your instructor having you create dynamic objects in your first programming course, but since this seems to be the case,
The reason you can't simply pass in a string object and assign the pointer to it is because a pointer is strictly an address to an already existing object. This would only work if the string were passed in by reference, and then the syntax might be:
void foo(std::string& str) {
name = &str;
}
When you pass in by value (without the ampersand) a copy of your object is being made to pass in via the parameter. This copy doesn't exactly have it's own home in memory yet, and it's definitely not the same home as what you passed in the parameter. So when you try to give it's address to the pointer, the compiler wants to complain because the address you're trying to save is going to disappear as soon as this scope is over with (the next } is hit).
You can, however, create a permanent object with a copied value. This is when you allocate dynamic memory on heap (normally it's on the stack). This would look something like:
void foo(std::string str) {
name = new std::string(str);
}
This will allow your name pointer to point to a newly created object on the heap. This is why you need the delete[] expression in your deconstructor, because the compiler can't manage dynamic memory for you, so you have to make sure to free it before the program ends.
Note that the [] are needed because a string is actually an array of characters. When you dynamically allocate an array, the [] notation will ensure that the memory until a sentinel value is read is freed. A sentinel character almost always refers to NULL or 0 on the ASCII chart.
If it were an int being freed, the syntax would just be:
delete x;
One last note. In your private section you have a variable called pi which is default initialized to 3.14. This is presumably because this is a value which will often be referred to and is common amongst all circles. When you have such common variables which will be the same in every instance of that class, you'll want to use what are called static variables. This is a variable which is allocated once, and which everyone associated with that variable has access to. Also, because you don't want pi to change, it should be const. It might look like this:
private:
static const double PI = 3.14;
What this will do is create one object called PI, and that exact same PI object will be used in every single circle you create. This will vastly cut down on the memory usage of that object, assuming you may create many. It is also good to note that typically const variables are capitalized, and non-const variables are not.
I agree with all of the points made by #RSahu, but will attempt to answer your specific issues.
Disclaimer: Using pointers as you do in this assignment is unnecessary and dangerous. It is even more unusual to require the use of them in this situation as pointers are a notoriously difficult concept for beginners to grasp.
Defining Constructors
You are defining each constructor twice.
Circle();
Circle::Circle()
{
// ...
}
and then
Circle(double, string);
Circle::Circle(double r, string n)
{
// ...
}
You only need to define them once. If you are declaring and defining them at the same time then the following is sufficient:
Circle()
{
// ...
}
If you want to declare and define them separately then you can do:
class Circle
{
public:
// Declare the constructor
Circle();
};
// Then later in some source, define it
Circle::Circle()
{
// ...
}
Implementing Constructors
You have crucial mistakes in both constructors (ignoring the fact that you are forced to use string*).
First,
Circle()
{
radius = 0.0;
*name = nullptr;
}
When you perform *name = nullptr you are dereferencing the name pointer and assigning it to nullptr.
This is bad for multiple reasons:
name has not been set. You are dereferencing a garbage pointer and setting it to nullptr. This is a crash.
Even if name had been initialized, you are setting the string object that it points to to nullptr which is another crash.
The proper way to initialize this would be as:
Circle()
: radius{ 0.0 },
name{ nullptr }
{
}
Let us look at the other constructor now.
Circle(double r, string n)
{
radius = r;
*name = n;
}
Again, radius is set correctly (mostly) but we have major issues with name.
name once again is uninitialized. So we are setting a non-existant string that name points to to n.
Now, here we are actually spared a bit of good luck. If you instead were performing
name = &n;
Then that would be bad as n is a temporary object. Once we leave the constructor our name would be pointing to garbage and you would crash the next time you try to access it.
But so how do we fix this constructor? I would do it like so:
Circle(double const r, string n)
: radius{ r },
name{ new string{n} }
{
}
In name{ new string{n} } we are setting name to a new string object that is initialized by the value in n.
Hope you are beginning to understand why in my disclaimer I do not approve of the requirement of using string* ...
Fixing setName
So, your implementation of setName is almost OK.
If we created an object of Circle using the second constructor it would be fine. Our string that name points to would simply be set the value of n.
But what if we are using a Circle created via the first constructor? Then we would be dereferencing a nullptr and attempting to set it the value of n. Crash.
I would actually fix this problem in your first constructor by changing it to:
Circle()
: radius{ 0.0 },
name{ new string }
{
}
So now we know name always points to a valid string object.
Finally, the Destructor
In the destructor you are using the incorrect delete[].
Use delete[] when deleting a dynamic array of objects. string is a single object, and thus should use delete.
I personally also think it is a good habit to set any deleted pointer to nullptr so that any common nullptr checks will work and not fail due to garbage.
~Circle()
{
delete name;
name = nullptr;
}
I want to output the values of the private class members Bankcode and AgentName. How can I do this from within my main() function, or in general, outside of the BOURNE class.
My initial code attempts are below:
#include <iostream>
#include <string>
using namespace std;
class BOURNE
{
string Bankcode ={"THE SECRET CODE IS 00071712014"} ; /*private by default*/
string AgentName={"Jason Bourne"}; /*private by default*/
public:
void tryToGetSecretCodeandName(string theName ,string theCode); //trying to get the private
void trytoGetAgentName( string name); // try to get name
};
//***********************defining member function**************************************
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode) //member defining function
{
Bankcode=theCode; //equalling name to the code here
AgentName=theName; //the samething here
cout<<theCode<<"\n"<<theName; //printing out the values
}
//************************main function*****************************
int main()
{
BOURNE justAnyObject; //making an object to the class
justAnyObject.tryToGetSecretCodeandName();
return 0;
}
Third Answer
Your code has two 'getter' style functions, but neither one takes no arguments. That is, both of your functions require arguments to be passed.
Your main function is calling get...CodeandName(), which has no arguments. As such, you get a compiler error, probably complaining about valid signatures, or arguments passed.
Edited Answer
If you only want to get the values, the typical (as far as I am aware) implementation is something like
std::string BOURNE::getCode()
{
return Bankcode;
}
std::string BOURNE::getName()
{
return AgentName;
}
int main()
{
BOURNE myAgent;
cout<< "The agent's name is : " << myAgent.getName() << endl;
cout<< "The agent's code is : " << myAgent.getCode() << endl;
}
Original Answer, left in because I feel like it's more useful
I suspect what you're asking is if you could do something like
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode)
{
if (Bankcode == theCode) {
cout<< "You correctly guessed the code : " << Bankcode << endl;
}
if (AgentName == theName) {
cout << "You correctly guessed the agent's name : " << AgentName << endl;
}
}
This will allow you to repeatedly guess at the name, and get output when you're correct.
If you wanted to disable this kind of guessing, then you could consider creating a new class (possibly derived from/based on std::string - but see this question for reasons to be careful!) and implement an operator== function which always returned false.
in my class, I have two methods that are responsible for getting and setting the value of a private variable. In another method that is outside of the class, I call the setter method and change the variable to another value. It works temporarily but always resets to the original value.
class storeItem
{
public:
void setPrice(int p)
{
price = p;
}
int getPrice()
{
return price;
}
storeItem(int p)
{
price = p;
}
private:
int price;
}
void changePrice(storeItem item)
{
int origPrice = item.getPrice();
item.setPrice(rand() % 10 + 1);
//The price is correctly changed and printed here.
cout << "This item costs " << item.getPrice() << " dollars and the price was originally " << origPrice << " dollars." << endl;
}
int main()
{
storeItem tomato(1);
changePrice(tomato);
//This would print out "This item costs *rand number here* dollars and the price was originally 1 dollars." But if I call it again...
changePrice(tomato);
//This would print out "This item costs *rand number here* dollars and the price was originally 1 dollars." even though the origPrice value should have changed.
}
I'm sure I'm making a silly beginners mistake and I appreciate any help in advance! :)
In C++, function parameters are passed by value unless you indicate otherwise. In your example, you are passing the storeItem by value to your function, so you are modifying a local copy inside of the function body. There is no effect on the caller side. You need to pass a reference:
void changePrice(storeItem& item)
^
Semantically, a reference is just an alias for an object, so you can consider the storeItem inside of your function to be the same as the one on the caller side.
When calling your function changePrice you don't call it by reference, nor with a pointer to the storeItem, so a copy is built.
Call it by reference instead:
void changePrice(storeItem& item)
{
//what you did before
}
Refer to this for further reference.
Hey i want to use the function wolves variable in the storyline and im trying to do this :
"\nYou awake on a beach to the sound of"<< Wolves().name; " starving and blood hungry,"
"\nThere is a Rock on the ground. You pick it up";
inventory.push_back("Rock");
But Wolves().name; there is an error as mentioned in the title. Why cant i do this?
Here is the code for the function Wolves:
void Wolves()
{
string name = "Wolves";
int health = 20;
hitPoints() +1;
}
You can't access variables defined in a function from outside the function in C++, but you can change it to a class:
class Wolves {
public:
string name;
// ...
Wolves(); // Constructor
//...
}
To access it you can use
Wolves wolve;
wolve.name = "whateverName"; // or set it in the constructor
cout << wolve.name << endl;
What you did in there is create local variables within the function. Once the function exits, they no longer exist. What you want to do is make a Wolves class and create public member variables to do what you want. For an example,
class Wolves {
public:
string name;
int health;
Wolves(string name, int a);
}
Then on the main function,
Wolves w("Bob", 20);
cout << "The name is: " << w.name << endl;
Will output "The name is: Bob"
void functions don't really do anything unless you pass the value in by reference. If you want to alter the object via void function, you should do something like
void Wolves(Wolves & wolfToChange)
{
wolfToChange.name = "Bob";
}
and that will directly alter the object.
You declared "name" as a local variable in a function called Wolves(), but the code that you were referring to expects the function Wolves() to return an object that has an accessible member name. That is why the compiler is complaining.
The way you wrote the code suggests that Wolves should be a class or struct, not a function.