Getter Setter for class - c++

I was working on homework that my instructor wanted me to write a class named Species with setter and getter functions. I wrote that code but I can't set or get any value when I run it. Can you help me?
class Species
{
private:
string name;
string country;
int population;
int growthrate;
public:
int year;
void setName(string NameS){
NameS=name;
}
void setCountry(string CountryS){
CountryS=country;
}
void setPopulation(int pop){
pop=population;
}
void setGrowthRate(int GrowRth){
GrowRth=growthrate;
}
void setYear(int syear){
syear=year;
}
string getName() {
return name;
}
string getCountry() {
return country;
}
int getPopulation() {
return population;
}
int getGrowthrate() {
return growthrate;
}
double e=2.71828182;
double calculatePopulation() {
int b=growthrate*year;
int a=pow(e,b);
return population*a;
}
};

First of all. Your class has fields like:
string name;
string country;
int population;
int growthrate;
And your methods are like:
void setName(string NameS){
NameS=name;
}
So you want to set NameS value to the name which makes no sense.
You should assign the field like name to be equal to nameS not the opposite.

Generally, a setter should look like this.
void setVariable(const VariableType& var){
this->var=var;
}
What you did was var=this->var.
Btw, you should make your getter-s const

You should use "this" keyword to set the value to object of the class.
this: to refer current class instance variable. The this keyword can be used to refer current class instance variable.
for example:
void setName(string name){
this.name=name;
}
void setGrowthRate(int growthrate){
this.growthrate=growthrate;
"this" is very helpful in please learn more about it.

Related

How to design c++ class in a way to have a base attributes and add attributes for few cases

I have a basic class ContactDetails which has a private variables as string name and string address. This ContactDetails data structure is used in my program for all entities. For some entities, I need other info on top of name and address, such as phone number, pin code etc. How to design the class.
class ContactDetails {
private:
std::string name;
std::string address;
public:
ContactDetails() {
this->name = "";
this->address = "";
}
std::string getName() { return name; }
std::string getAddress() { return address; }
void setName(std::string n) { name = n; }
void setAddress(std::string n) { address = n; }
}
class ContactDetailsHelper {
public:
ContactDetails getX() {
ContactDetails obj;
obj.setName("X");
obj.setAddress("New York");
return obj;
}
ContactDetails getY() {
//Y has phone number, pin code, county code etc details available.
ContactDetails obj;
obj.setName("Y");
obj.setAddress("Chicago");
//need to set more details in the object
return obj;
}
If we take phone number, pin code, county code as a private member in ContactDetails class, most of the time it would be empty. So how to design the class in such a way like extra details we could put it in another class and if needed for any entity we could use them.

C++ Null output when a function is called

Below is a snippet of code from my main program
My H file
class Person{
public:
std::string name;
int rangeStance;
int initialStance;
Person(std::string name, int rangeStance, int initialStance){
name = name;
rangeStance = rangeStance;
initialStance = initialStance;
setName(getName());
setRangestance(getRangeStance());
setinitalStance(getRangeStance());
}
Person();
void setName(std::string name);
void setRangestance(int range);
void setinitalStance(int stance);
std::string getName();
int getRangeStance();
int getinitalStance();
double impact(int rangeStance, int initalStance);
};
class Leader: public Person {
public:
int popularity;
int totalcountryVotes;
Leader(std::string name, int rangeStance, int initialStance,int popularity, int totalcountryVotes)
:Person(name, rangeStance, initialStance), popularity(popularity), totalcountryVotes(totalcountryVotes){
popularity = popularity;
totalcountryVotes = totalcountryVotes;
setPopularity(getPopularity());
setTotalcountryVotes(getTotalcountryVotes());
}
Leader();
void setPopularity(int popularity);
void setTotalcountryVotes(int totalcountryVotes);
int getPopularity();
int getTotalcountryVotes();
};
The corresponding functions in the main cpp file.
Person::Person() {
}
void Person::setName(string Name)
{
name = Name;
}
string Person::getName() {
return name;
}
void Person::setRangestance(int Range)
{
rangeStance = Range;
}
int Person::getRangeStance() {
return rangeStance;
}
void Person::setinitalStance(int stance)
{
initialStance = stance;
}
int Person::getinitalStance() {
return initialStance;
}
Leader::Leader() {
}
void Leader::setPopularity(int popularity) {
popularity = popularity;
}
void Leader::setTotalcountryVotes(int totalcountryVotes) {
totalcountryVotes = totalcountryVotes;
}
int Leader::getPopularity() {
return popularity;
}
int Leader::getTotalcountryVotes() {
return totalcountryVotes;
}
Within main the needed funtions are called appropriately
int main(int argc, char* argv[]) {
Leader labourLeader("George Lopez",100,50,50, 75);//sets record for the labour party leader
cout << "--Party Leader--" << endl;
cout << labourLeader.getName() << endl;
return 0;
}
However when this snippet of code is compiled, no outcome is returned where it should be printing out "George Lopez". Im fairly "noob" with c++, am i using my contructor right or should I be delcaring it within my h file? Thankyou.
A couple of things wrong in this code
Person(std::string name, int rangeStance, int initialStance){
name = name;
rangeStance = rangeStance;
initialStance = initialStance;
setName(getName());
setRangestance(getRangeStance());
setinitalStance(getRangeStance());
}
Firstly it's not necessary to call setters and to do assignments, so lets drop those, leaving
Person(std::string name, int rangeStance, int initialStance){
name = name;
rangeStance = rangeStance;
initialStance = initialStance;
}
Now think about what name = name does. Does that look curious to you at all? It takes the parameter name and assigns it to the parameter name! The member variable also called name is completely unchanged. This situation where one name hides another similar name is called shadowing.
Person(std::string name, int rangeStance, int initialStance) {
name = name;
What's happening there is that it's just overwriting the parameter with itself, rather than copying it to the member variable. That's because the name lookup rules for unqualified names at that point prefer the parameter to the member variable. That means the member variable is being left at its constructed state, an empty string.
There are a few ways to fix this. The first is to simply name them differently so that there's no ambiguity, such as the common method of prefixing member variables with m_. That way, the statement becomes the more explicit:
m_name = name;
Another alternative is to be explicit about the one you're assigning to so that it's no longer unqualified:
this->name = name;
A third is to use initialiser lists where the rules are slightly different in that it uses the member variable outside the parentheses and does normal unqualified lookup within the parentheses:
Person(std::string name, int rangeStance, int initialStance)
: name(name)
, rangeStance(rangeStance)
, initialStance(initialStance)
// ^ ^
// | |
// | +- normal lookup, passed-in parameter.
// +--------------- member variable.
{
};
And there's no need to have all those other statements in the constructor, such as setName(getName()), since you've already set the name.

C++: how to make getters and setters work with an empty constructor

First of all, I have only learned a little bit of Java before. It's been only a few days since I started getting friendly with C++ so please don't take this question so basic and please don't degrade my question.
I made a simple source code as follows:
#include <iostream>
using namespace std;
class Car {
public:
void setBrand(string name);
void setPrice(double price);
string getBrand();
double getPrice();
Car();
Car(string name);
Car(string name, double price);
private:
string name;
double price;
};
Car::Car() {
}
Car::Car(string name) {
name = name;
}
Car::Car(string name, double price) {
name = name;
price = price;
}
void Car::setBrand(string name) {
name = name;
}
void Car::setPrice(double price) {
price = price;
}
string Car::getBrand(void) {
return name;
}
double Car::getPrice(void) {
return price;
}
int main() {
Car car;
car.setBrand("Nissan");
car.setPrice(30000);
cout << "Brand: " << car.getBrand() << endl;
cout << "Price: " << car.getPrice() << endl;
return 0;
}
I wanted to make a code that creates an empty instance of a class called Car, set the field values later and print them out on the console.
The code did not make any errors during the compile, but the result I see was totally different from what I expected. It didn't show the brand name and the price was looking even weird, as follows.
Brand:
Price: 6.95322e-310
Somebody help me out! Thank you very much indeed in advance.
The problem you have is that you override the member names with function parameters. You can use this-> to make it explicit or name the member differently.
For example:
void Car::setBrand(string name) {
this->name = name;
}
Or:
void Car::setBrand(string new_name) {
name = new_name;
}
In your constructor and setters, you make no differentiation between the local parameter and the class member.
name = name;
Both the function parameter and the class member are called name. Currently the compiler is assigning the parameter value to itself, and not affecting the class member at all. This is because the function parameter is in a more immediate scope.
Possible solutions:
Specify this when referring to the class member: this->name = name;.
Rename the function parameter: name = _name;.
For the constructor, use initializer lists:
Car::Car(string name, double price)
: name(name)
, price(price)
{ }
There's too much wrong with your code to describe it in prose, so let me present a fixed implementation, and I leave it to you to spot the difference:
#include <string>
class Car
{
private:
static constexpr double kNoPrice = -1.0;
static constexpr const char* kNoName = "[no name]";
public:
// Main constructor: constructs a car with the given name and price.
Car(std::string name, double price)
: name_(std::move(name))
, price_(price)
{}
// Convenience constructors:
Car() : Car(kNoName, kNoPrice) {}
Car(std::string name) : Car(std::move(name), kNoPrice) {}
// Accessors:
const std::string& getBrand() const { return name_; }
void setBrand(std::string name) { name_ = std::move(name); }
double getPrice() const { return price_; }
void setPrice(double price) { price_ = price; }
private:
std::string name;
double price;
};
Some random notes, in no particular order:
Use correct names. It's std::string, not string, mate or buddy. Never ever be abusing namespace std.
Include headers for external names that you need.
Reading uninitialized values is undefined behaviour, so none of your constructors should leave fields uninitialized (like price_).
Give private members consistent names (e.g. foo_ in my example).
Accessors should be const-correct.
Convenience constructors should delegate to one single work-horse constructor.
Pick sensible defaults for initial values of defaulted fields and make them discoverable.
Use move semantics when taking ownership of dynamically managed data (strings, dynamic containers, etc.).

Segmentation fault when getting QString

Strange problem, already looked into with several colleagues...
Using Qt Creator and Qt 4.8.5
define an object
set a number of values with setters
request values with a getters
result: getting an int no problem, all other values give segmentation fault
but with breakpoint in debugger the values are correctly shown, so they are in the object!
same code worked before, problem "just appeared". Compiler issue?
private:
int id;
QString name;
public;
int getId() { return this->id; } // OK
void setId(int id) { this->id = id; }
QString getName() { return this->name; } // SIGSEGV
void setName(QString name) { this->name = name; }
Any ideas? Same issue known?
UPDATE
Changed code to this, based on comments, still same issue
private:
int id;
QString name;
public;
int getId() { return id; } // OK
void setId(int setTo) { id = setTo; }
QString getName() { return name; } // SIGSEGV
void setName(QString setTo) { name = setTo; }
I was facing similar issue. Although I could not find the root cause of this issue, I have another observation.
If we define the getter functions outside the class declaration using scope resolution operator the code works.
QString MyClass::GetX(void) {
return mX;
}
QString MyClass::GetY(void) {
return mY;
}
class MyClass
{
public:
MyClass(){}
/* Functions for setting mX and mY strings. */
QString GetX(void);
QString GetY(void);
isDataAvailable()
{
return mAvailable;
}
private:
bool mAvailable;
QString mX;
QString mY;
};
As I understand, in C++, if we define a function within class declaration, by default it is inline... so the issue could be something related with inlining of the functions.
thinking further about the way objects are created in memory, I thought that a QString maybe doesn't reserve fixed number of bytes, which could be the cause of this strange behavior and guess what, a dummy change solved my problem...
This feels like a really "dirty" solution, but at least I can go on with my work ;-)
But any idea's on the root cause would really be appreciated! Thanks already for all the valuable comments!!!
private:
QString name; // FIRST DEFINE QSTRING
int id; // THEN DEFINE INT
public;
int getId() { return id; } // OK
void setId(int setTo) { id = setTo; }
QString getName() { return name; } // OK
void setName(QString setTo) { name = setTo; }

How can I create multiple items with one class in C++?

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.