In this code, I have created a vector of accounts in class bank, and (by my understanding) whenever I am adding an account, the bank class will create a different account object and push it into vectors, and when account constructor will initialize, it will make a different copy of customers every time a new account will be made through account vector in bank class - Please tell me if my understanding of this thing is clear? Here I am serially assigning account number.
`
class customer
{
string customerName;
string customerAddress;
int phoneNumber;
public:
customer(string customerName, string customerAddress, int phoneNumber)
{
this->customerName=customerName;
this->customerAddress=customerAddress;
this->phoneNumber=phoneNumber;
}
};
class account
{
customer customerObject;
int accountNumber;
static int accountBalance;
public:
account(int accountNumber, int accountBalance)
{
customer customerObject(customerName, customerAddress, phoneNumber);
this->accountNumber=accountNumber;
this->accountNumber=accountNumber;
}
int getBalance()
{
return accountBalance;
}
};
int account::accountBalance=0;
class bank
{
vector<account> accountContainer;
static int accountNumber;
int accountBalance=0;
public:
void addAccount(int deposit, string customerName, string customerAddress, int phoneNumber)
{
account accountObject(++this->accountNumber, this->accountBalance+deposit, customerName, customerAddress, phoneNumber);
accountContainer.push_back(accountObject);
}
void getBalance(int accountNumber)
{
if(accountNumber<=this->accountNumber)
{
return accountContainer[accountNumber-1].getBalance;
}
}
}
};
int bank::accountNumber=0;
int bank::accountBalance=0;
`
You are mostly correct. Only a single new customer object will be created each time you create a new account.
#include <string>
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class customer
{
string m_customerName;
string m_customerAddress;
int m_phoneNumber;
public:
customer(const std::string& customerName, const string& customerAddress, int phoneNumber)
{
m_customerName=customerName;
m_customerAddress=customerAddress;
m_phoneNumber=phoneNumber;
}
};
class account
{
customer m_customerObject;
int m_accountNumber;
int m_accountBalance;
public:
account(int accountNumber, int accountBalance, const std::string& customerName, const string& customerAddress, int phoneNumber):
m_customerObject(customerName, customerAddress, phoneNumber)
{
m_accountNumber=accountNumber;
m_accountBalance=accountBalance;
}
int getBalance()
{
return m_accountBalance;
}
};
class bank
{
vector<account> accountContainer;
public:
bank()
{
}
void addAccount(int accountNumber, int accountBalance, int deposit, const string& customerName, const string& customerAddress, int phoneNumber)
{
account accountObject(accountNumber, accountBalance+=deposit, customerName, customerAddress, phoneNumber);
accountContainer.push_back(accountObject);
}
int getBalance(int accountNumber)
{
try{
int balance = accountContainer.at(accountNumber).getBalance();
}
catch(std::exception& ex)
{
std::cout<<"Exception: "<<ex.what()<<std::endl;
}
}
};
int main()
{
bank b;
b.addAccount(1, 100, 2000,"John","222 Foo Street", 2222);
b.addAccount(2, 3000, 2000,"Roger","101 Apple Lane", 1111);
std::cout<<b.getBalance(0)<< std::endl;
std::cout<<b.getBalance(1);
return 0;
}
accountContainer.push_back(accountObject);
will copy accountObject into the accountContainer vector. So you have two instances of the account class. When addAccount returns, accountContainer goes out of scope and it is destroyed but the instance in the vector still exists.
See
http://www.cplusplus.com/reference/vector/vector/push_back/
it says this for push_back
Add element at the end
Adds a new element at the end of the vector, after its current last element. The content of val is copied (or moved) to the new element.
The compiler is however allowed to do all kinds of optimization as long as the end result is correct. Therefore it can be difficult to say exactly which functions (aka constructors/destructors) will be called during execution of the function. It may depend on optimization level. But the end result will always be correct. In this case the end result is that the vector holds an instance of the accountclass.
Since your accountclass contains a customer member each instance of account will of cause have its own customer instance.
Your constructor for account seems wrong as you make a local customer variable inside the constructor. Instead you shall just initialize the member variable. It could look like:
account(int account_number, int account_balance) :
customerObject(customerName, customerAddress, phoneNumber)
{
this->accountNumber=account_number;
this->accountBalance=account_balance;
}
or even:
account(int account_number, int account_balance) :
customerObject(customerName, customerAddress, phoneNumber),
accountNumber(account_number),
accounBalance(account_balance)
{}
Related
New to classes and objects in c++ and trying to learn a few basics
I have the class TStudent in which the Name, Surname and Age of student are stored, also I have the constructor which is accessed in main and inserts in the data.
What I want to do is: having the class TRegistru, I have to add my objects data in it, in a way that I can store it there, then I could save the data in data.bin and free the memory from the data, then I want to put the data back in the class and print it out.
The question is: In what way & what is the best way to add my objects in the second class, so that I could eventually work with them in the way I've described in the comments, so that I won't have to change nothing in main
Here's my code so far:
#include <iostream>
using namespace std;
class TStudent
{
public:
string Name, Surname;
int Age;
TStudent(string name, string surname, int age)
{
Name = name;
Surname = surname;
Age = age;
cout <<"\n";
}
};
class TRegistru : public TStudent
{
public:
Tregistru()
};
int main()
{
TStudent student1("Simion", "Neculae", 21);
TStudent student2("Elena", "Oprea", 21);
TRegistru registru(student1);//initialising the object
registru.add(student2);//adding another one to `registru`
registru.saving("data.bin")//saving the data in a file
registru.deletion();//freeing the TRegistru memory
registru.insertion("data.bin");//inserting the data back it
registru.introduction();//printing it
return 0;
}
Hence the question is about passing data from A to B, I will not comment on the file handling portion.
This can be done in multiple ways, but here is one of the simplest and most generic. By calling TRegistru::toString() you serialize every TStudent added to TRegistru into a single string which then can be easily written to a file.
Demo
class TStudent
{
public:
std::string Name, Surname;
int Age;
std::string toString() const
{
return Name + ";" + Surname + ";" + to_string(Age);
}
};
class TRegistru
{
public:
void add(const TStudent& student)
{
students.push_back(student);
}
void deletion()
{
students.clear();
}
std::string toString() const
{
std::string ret{};
for(const auto& student : students)
{
ret += student.toString() + "\n";
}
return ret;
}
std::vector<TStudent> students;
};
I'm new in oop and don't know how to specify this problem globally. I have two classes. Client
class Client
{
private:
int code;
string name;
public:
Client(int c, string n);
int getCode();
string getName();
};
Client::Client(int c, string n)
{
this->code = c;
this->name = n;
}
int Client::getCode()
{
return this->code;
}
string Client::getName()
{
return this->name;
}
and Account
class Account
{
private:
int number;
double balance;
double interestRate;
Client* owner;
};
and I have method like this:
Client* Account::getOwner()
{
return this->something;
}
Can you please tell me, how can I get client's code and name from this method?
Can you please tell me, how can I get client's code and name from this method?
The method is called getOwner. A method called getOwner should ... get ... the owner. Nothing else.
If you want to get the owner's name, either write a new method
string getOwnerName() const { return owner->getName(); }
or ...
(better because it reduces coupling between the Account and Client classes, possibly worse because it depends on exposing the owner directly, but then you're already doing that ...)
... just delegate this to the client code:
cout << account->getOwner()->getName();
I'm trying to initialize variables from two classes in one object.
For example, in the main function, I have:
Worker Object("Kenny Smith",23425,"1/2/2012", "Third", 1, 12.00);
In the worker class, I have the function:
Worker::Worker(Store Name, Store Num, Store Date, string Shift, int ShiftNumber, double Rate)
{
Store name = Name;
Store number = Num;
Store date = Date;
shift = Shift;
shiftnumber = ShiftNumber;
rate = Rate;
}
When I try to compile the main function, it gives me the error that "no instance of constructor Worker::Worker matches the argument list", because name, number, and date are from the Store class. I've included the Store header in the Worker class.
How will I make it work without separating the functions?
The constructor takes a string from the Store class "Kenny Smith", an integer from the Store class 23425, a string from the Store class "1/2/2012", another string from the worker class "Third", an integer from the worker class 1, and a double from the worker class 12.00.
It seems that your Store class takes string inputs.
So, I guess this should work
Worker Object("Kenny Smith", "23425","1/2/2012", "Third", 1, 12.00);
Note the second argument is now a string.
Edit: Based on the comment
class Store
{
public:
Store(string name, int num, string data) { ... }
Store(string name) { ... }
Store(int num) { ... }
}
I would advise reading a C++ book to understand how constructors work.
Edit
class Store
{
string name_;
int num_;
int date_;
public:
Store(string name, int num, string date) { ... }
Store(string name) { ... }
Store(int num) { ... }
const string& name() const { return name_ };
string& name() {return name_};
}
Now from your Worker class
Worker(Store a, .... )
{
a.name() = string("ABC");
}
Okay, so I have an assignment for a class that requires us to use a series of classes together, to simulate a police officer issuing a ticket.
Here's how it works:
ParkedCar class:
To know the cars make, model, color, license number, and the number of minutes
that the car has been parked
ParkingMeter Class:
know how much time has been purchased
ParkingTicket Class:
know make, model, color, license of the car, calculate the fine, as well as the name and badge number of the officer issuing the ticket
PoliceOfficer Class:
Know the name a badge number of the officer
AND
Examine ParkedCar and ParkingMeter objects and determine if a ticket is needed, if so, generate a ParkingTicket object.
Here's what code I have so far:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<ctime>
using namespace std;
class ParkedCar
{
string sMake;
string sModel;
string sColor;
string sPlate;
int iMinsParked;
public:
ParkedCar();
string getMake() const
{ return sMake; }
void setMake(string temp)
{ sMake = temp; }
string getModel() const
{ return sModel; }
void setModel(string temp)
{ sModel = temp; }
string getColor() const
{ return sColor; }
void setColor(string temp)
{ sColor = temp; }
string getPlate() const
{ return sPlate; }
void setPlate(string temp)
{ sPlate = temp; }
int getMins() const
{ return iMinsParked; }
};
ParkedCar::ParkedCar()
{
srand(time(NULL));
iMinsParked = (rand() % 10000);
}
class ParkingMeter
{
int iMinsPurch;
public:
void setMins(int temp)
{ iMinsPurch = temp; }
int getMins() const
{ return iMinsPurch; }
}
class Ticket : public ParkedCar
{
public:
string getName()
{ return sName; }
int getBadge()
{ return iBadge; }
};
class Officer
{
string sName;
int iBadge;
public:
friend string Ticket::getName();
//{ return sName; }
friend int Ticket::getBadge();
//{ return iBadge; }
};
int main()
{
ParkedCar Park;
cout << endl << endl;
cout << Park.getMins();
cout << endl << endl;
return 0;
}
Where I'm confused is mostly on the Ticket and Officer classes. The assignment clearly wants Ticket to have it's own information from all the other classes, but I'm not sure how to pass that information along. I've tried making it a child class of ParkedCar, but I just get a multiple definitions error. And I can't get the friend functions to work. I've tried them both ways and if I make them within Ticket, it tells me Officer isn't defined. And I'm really confused on how I'm supposed to write code for Officer generating an instance of Ticket when nothing has actually been initialized yet.
So:
How do I get all the information into the Ticket class?
How would I get Officer to generate an instance of Ticket?
Please keep in mind this is a STUDENT assignment, not something professional. I just want to do what the assignment says. I'm not interested in ways "around" the problem, because that's not what the prof wants.
Thanks in advance for your time. :D
Firstly: learn to use constructors. All this stuff you're setting...it is integral to the identity of a car, or a cop, etc. It should have been provided when the object was built. C++ isn't Java; quit treating classes like Java beans. :P
Secondly, a Ticket is not a ParkedCar. It associates with a car, but is not one itself. Consider instead:
class Ticket {
ParkedCar violator;
Officer issuer;
public:
Ticket(const Officer &cop, const ParkedCar &car) :
violator(car), issuer(cop) {
}
ParkedCar getCar() { return violator; }
Officer getOfficer() { return issuer; }
// Note, no mutators here!
// The biggest reason you had to have mutators, is that your construction
// was incomplete.
// The info associated with a Ticket should not be modified once the ticket
// is written. And since the constructor has all the info needed, there's no
// need to provide a way to modify them.
};
So an Officer doesn't need to know about the potentially-intricate details of a car, or exactly what info a Ticket needs. He can just hand himself and the car over to the constructor, and trust that it will extract whatever info it needs. (In this case, we just store copies of both items.)
class Officer {
std::string name;
int badge_number;
public:
Officer(const std::string& name, int badge) : name(name), badge_number(badge) { }
public std::string getName() { return name; }
public int getBadgeNumber() { return badge_number; }
Ticket writeTicketFor(const ParkedCar &violator) {
return Ticket(*this, violator);
}
};
I have the class Furniture with:
Furniture.h:
#include <iostream>
#include <string>
using namespace std;
class Furniture {
public:
Furniture();
~Furniture();
void setname(string name);
void setprice(double price);
double getprice();
string getname();
virtual void printSpecs();
private:
string name;
double price;
protected:
static int NumberOfItems;
int Id;
};
furniture.cpp:
#include "furniture.h"
Furniture::Furniture() {
}
Furniture::~Furniture() {
}
void Furniture::setname(string name) {
this->name = name;
}
string Furniture::getname()
{
return this->name;
}
void Furniture::setprice(double price) {
this->price = price;
}
double Furniture::getprice() {
return this->price;
}
void Furniture::printSpecs() {
cout<<"Price: "<<this->price<<endl;
cout<<"Name: "<<this->name<<endl;
}
int main() {
Furniture *model = new Furniture();
model->setname("FinalDestiny");
model->setprice(149.99);
model->printSpecs();
delete model;
}
Everything works fine but I want to add multiple furniture items with the same class and just update the NumberOfItems. Is there any way to do that?
Also, is my code ok? I mean, how can I improve it? I'm quite new to OOP and I'd like to learn some good practices.
Thanks.
The idea is conceptually broken. You cannot do that; you really need different objects.
Alternatively, if you really want to have multiple identical items, you can create one item and create multiple pointers to it, and maintain a separate count for the number of active items. A shared_ptr does that for instance.
That said, your code shouldn’t use pointers at all, this is a common anti-pattern in C++ code. Furthermore, your code probably shouldn’t have setters, provide a proper constructor instead:
int main() {
Furniture model("FinalDestiny", 149.99);
model.printSpecs();
}
Much shorter, simpler, and no possiblity of leaking memory.
To keep track of the number of items, you can update the number of items in the constructor:
Furniture::Furniture() {
Id = NumberOfItems++;
}
and decrement in the destructor if you want:
Furniture::~Furniture() {
NumberOfItems--;
}
To access the item by Id, you need to have an extra manager class or use a map:
std::map<int,Furniture*> items;
which you can pass as parameter to the constructor and update it there:
Furniture::Furniture(std::map& items) {
Id = NumberOfItems++;
items[Id] = this;
}
And, outside, you can simply retrieve items with:
Furniture* f = items[3];
I would write in this way
#include <iostream>
#include <string>
using namespace std;
class Furniture {
public:
Furniture(string name = "", double price = 0)
: name(name), price(price), Id(NumberOfItems++)
{}
Furniture(const Furniture &f)
: name(f.getname()), price(f.getprice()), Id(NumberOfItems++)
{}
void setname(string name) { this->name = name; }
void setprice(double price) { this->price = price; }
double getprice() const { return price; }
string getname() const { return name; }
virtual void printSpecs() {}
private:
string name;
double price;
protected:
static int NumberOfItems;
int Id;
};
int Furniture::NumberOfItems;
int main_furniture(int, char **)
{
Furniture a("product 1", 100);
Furniture x(a), y(a), z(a);
}
I've inlined just to simplify. What's interesting to you should be the copy constructor implementation, and (OT) you forget the const on getter...
Just increment NumberOfItems in the constructor, and decrement it in the destructor.
Store the furniture instances in an array or better in a vector. You can access them with an index or iterator. The NumberOfItems field doesn't belong in the furniture class, an instance of furniture shouldn't know about how many furniture items there are in the system. Use the size () method from vector to get the furniture item count.