Anyone can help me to make function using OOP? How to be able to make the function of finding the average of height of students with OOP?
class Person
{
//data members
private:
string name;
int age;
int height;
float weight;
//member functions
public:
void setPerson(string n, int a, int h, float w)
{
name=n;
age=a;
height=h;
weight=w;
}
void setName(string n) { name=n; }
void setAge(int a) { age=a; }
void setHeight(int h) { height=h; }
void setWeight(int w) { weight=w; }
string getName() {return name;}
int getAge() {return age;}
int getHeight() {return height;}
float getWeight() {return weight;}
};
int main()
{
Person p[100];
int x;
cin >> x;
string name;
int age;
int height;
float weight;
for(int i=0; i<x; i++)
{
cin >> name >> age >> height >> weight;
p[i].setName(name);
p[i].setAge(age);
p[i].setHeight(height);
p[i].setWeight(weight);
}
..............
my input are :
3 (number of person)
jason 20 185 70.50 (name age height weight)
emma 19 165 55.55
yerry 25 164 65.10
output :
171.33
Once you have your Persons recorded, it's just a matter of calculating the average height. It should not be a member function of Person, as the class is intended to represent a single Person. An average height is not a property or action taken on/by/to a single Person, so we just calculate it in main().
I've noted changes that I made to your code.
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
class Person {
// data members
private:
std::string name;
int age;
int height;
float weight;
// member functions
public:
// CHANGE: Change function to constructor
Person(std::string n, int a, int h, float w)
: name(n), age(a), height(h), weight(w) {}
void setName(std::string n) { name = n; }
void setAge(int a) { age = a; }
void setHeight(int h) { height = h; }
void setWeight(int w) { weight = w; }
std::string getName() { return name; }
int getAge() { return age; }
int getHeight() { return height; }
float getWeight() { return weight; }
};
int main() {
std::vector<Person> p; // CHANGE: Switch from C-array to std::vector
int x;
std::cin >> x;
std::string name;
int age;
int height;
float weight;
for (int i = 0; i < x; i++) {
std::cin >> name >> age >> height >> weight;
p.emplace_back(name, age, height,
weight); // CHANGE: Take advantage of vector functionality
// to build Person directly into vector
}
// ADDITION: Calculating average height, std::for_each is subjective here,
// this could have easily been a range-based for loop.
double avgHeight = 0.0;
std::for_each(p.begin(), p.end(), [&avgHeight, size = p.size()](auto person) {
avgHeight += static_cast<double>(person.getHeight()) / size;
});
std::cout << std::fixed << std::setprecision(2) << avgHeight << '\n';
}
Output:
171.33
std::for_each may look goofy, but it's literally just summing heights and dividing by the number of Persons. Like I noted, it could also just be a range-based for loop. I prefer the range-based for loop in this case; I only have std::for_each() because it was a quicker change from my failed attempts at coercing std::reduce to work.
double avgHeight = 0.0;
for (auto i : p) {
avgHeight += static_cast<double>(i.getHeight()) / p.size();
}
The type of i would be better specified as const auto&, but your getters are not marked as const.
You could add a parent struct for Person (call it Individual or something) that has a vector pointer as a member variable. For example, std::shared_ptr<std::vector<double> > Students ( new std::vector<double>() ); The struct would have all the public functions that Person has as pure virtual functions.
Then, add a new void function to Person that derefs Students, and pushes back the height of a new student. Next, you add another function (returning a double or float) that loops through Students to take the sum of the students' heights, and divides it by the size() of the vector.
All Person objects will have pointers to a single Students vector, so every time you push back the height of a new student, it will go to the same place.
Related
INPUT STDIN -> <street> <city> <house_number> <number of objects of house> <object1> <price1> .......<object-n> <price-n> (until EOF)
I need to use the "add" method in the "House" Class.
objective: adding the specific n objects of each House in "House" class
This is what i did since now:
#include <iostream>
#include <utility>
#include<vector>
#include<string>
using namespace std;
class Object {
public:
string valuable;
float price;
public:
Object() : Object("",0) {}
Object(string v, float p) : valuable(std::move(v)), price(p) {}
string getValuable() {
return valuable;
}
float getPrice() {
return price;
}
};
class House{
public:
string street;
string city;
uint32_t number;
vector<Object>valuables;
public:
House(): House("","",0){}
House(string s,string c,uint32_t n): street(std::move(s)),city(std::move(c)),number(n){}
string getStreet() {
return street;
}
string getCity() {
return city;
}
uint32_t getNumber() {
return number;
}
uint32_t getValuablesSize() {
return valuables.size();
}
Object getValuable(uint32_t x){
return valuables[x];
}
void add(Object a){
valuables.emplace_back(a);
}
};
float getTotalPrice(House a) {
float sum = 0;
for (int i = 0; i < a.getValuablesSize(); i++) {
sum +=a.valuables[i].getPrice();
}
return sum;
}
int main() {
vector<Object>obj;
vector<House>house;
char object[30],street[30],city[30];
float price;
uint32_t house_number;
int n;
while(cin>>street>>city>>house_number>>n) {
house.emplace_back(string(street),string(city),house_number);
Object a;
for(int i=0;i<n;i++){
cin>>object>>price;
obj.emplace_back(object,price);
a.valuable=object;
a.price=price;
for(int k=0;k<house.size();k++)
house[k].add(a);
}
}
for(int i=0;i<obj.size();i++){
cout<<obj[i].getValuable()<<" "<<obj[i].getPrice()<<endl;
} // trying to print the object vector
for(int i=0;i<house.size();i++){ //trying to verify if i have the correct input
cout<<house[i].getStreet()<<" "<<house[i].getCity()<<" "<<house[i].getNumber()<<" ";
for(int j=0;j<house[i].getValuablesSize();j++) {
cout << house[i].valuables[j].valuable<< " "<<house[i].valuables[j].price<<" ";
}
cout<<endl;
}
return 0;
}
That's what i think:
-when i read <house_number> ,read the objects and prices and then the add method should be used in order to have the vector<Object>valuables usable.
It's necesarly to check if the input is stored corectly in the class "House", in order to continue summing the objects in every house
With the statements
for(int k=0;k<house.size();k++)
house[k].add(a);
you add the current "valuable" object to every house that has been created thus far.
I suggest you instead create the house object separately, then add the valuable objects to the current house, and after that add the house to your collection of houses.
Perhaps something like:
std::string street;
std::string city;
unsigned house_number;
unsigned n;
while(std::cin >> street >> city >> house_number >> n) {
House current_house(street, city, house_number);
std::string object;
float price;
for(int i = 0; i < n && std::cin >> object >> price; ++i) {
Object a(object, price)
current_house.add(a);
}
house.push_back(current_house);
}
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
class Shape{
protected:
int _r;
int _w;
int _h;
public:
Shape(double r) : _r(r) {}
Shape(double w, double h) : _w(w), _h(h) {}
virtual double area(vector<Shape *>){
cout << "shape:: area " << endl;
return _r;
}
};
class Circle : public Shape{
public:
Circle(double r) : Shape(r) {}
double area(vector<Shape *>) { return _r*_r*atan(1)*4.0; }
};
class Triangle : public Shape{
public:
Triangle(double s) : Shape(s) {}
double area(vector<Shape *>) { return sqrt(3) * pow(_r, 2) / 4; }
};
class Rectangular : public Shape{
public:
Rectangular(double w, double h) :Shape(w, h) {}
double area(vector<Shape *>) { return _w * _h ;}
};
int main()
{
int n;
char info;
int value;
int value2;
double sum;
vector<Shape > collection;
vector<int> answer;
sum = 0;
cin >> n;
for(int i = 0 ; i < n; i++)
{
cin >> info;
if (info == 'C')
{
cin >> value;
Circle c(value);
collection.push_back(c);
}
else if (info == 'R')
{
cin >> value;
cin >> value2;
Rectangular r(value, value2);
collection.push_back(r);
}
else
{
cin >> value;
Triangle t(value);
collection.push_back(t);
}
}
for (int i = 0; i < n ; i++)
{
sum += collection[i].area(&collection[i]);
}
cout << sum << endl;
}
As you can see , I used an abstract class Shape, and the three concrete class , Circle, Rectangular, Triangle.
And I wanna sum areas of all shapes. such as
First input represents how many shapes we have to calculate. C for circles, R for rectangle, and T for regular triangles.
And I want to override function "area" of which parameter is vector.
But my error is
How can I solve this no viable conversion from 'std::__1::__vector_base<Shape, std::__1::allocator >::value_type'
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
class Shape{
protected:
int _r;
int _w;
int _h;
public:
Shape(double r) : _r(r) {}
Shape(double w, double h) : _w(w), _h(h) {}
virtual double area(vector<Shape *>) = 0;
};
class Circle : public Shape{
public:
Circle(double r) : Shape(r) {}
double area(vector<Shape *>) { return _r*_r*atan(1)*4.0; }
};
class Triangle : public Shape{
public:
Triangle(double s) : Shape(s) {}
double area(vector<Shape *>) { return sqrt(3) * pow(_r, 2) / 4; }
};
class Rectangle : public Shape{
public:
Rectangle(double w, double h) :Shape(w, h) {}
double area(vector<Shape *>) { return _w * _h ;}
};
int main()
{
int n;
char info;
int value;
int value2;
double sum;
vector<Shape*> collection;
vector<int> answer;
sum = 0;
cin >> n;
for(int i = 0 ; i < n; i++)
{
cin >> info;
if (info == 'C')
{
cin >> value;
Circle c(value);
collection.push_back(&c);
}
else if (info == 'R')
{
cin >> value;
cin >> value2;
Rectangle r(value, value2);
collection.push_back(&r);
}
else
{
cin >> value;
Triangle t(value);
collection.push_back(&t);
}
}
for (int i = 0; i < n ; i++)
{
sum += collection[i]->area(collection);
}
cout << fixed << setprecision(2) << sum << endl;
}
I changed and fix!
Polymorphism does not work with concrete classes!
By declaring vector<Shape> collection;, you declare a vector of Shape, not of Circle, Triangle or Rectangular. You probably want collection to be of type vector<Shape*> to be able to utilize polymorphism.
Another issue with your code is that you don't pass collection, which is of type vector<Shape>, but collection[i] which just is of type Shape.
This would probably also explain your error, since your compiler most likely wants to parse Shape into vector<Shape*> since that's type of the argument of area. This is not possible, and therefore probably causes your compiler error.
Also, if you want to pass just collection, you'd have to make sure the types are matching. vector<Shape> is not implicitly convertable into vector<Shape*>
I need to creat an object Pokemon in the main()
that assign it into the class PokemonWorld, and let the PokemonWolrd to decide which PokemonStation is this Pokemon need to go
I tired get the data separatly (get name and hp) and get together(get a Pokemon class)
but both fail
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
class Pokemon {
public:
Pokemon() {};
Pokemon(char x[], int n) {
strncpy_s(name, x, 10);
hp = n;
};
private:
char name[10];
int hp;
};
class PokemonStation {
private:
Pokemon **list= new Pokemon*[1000];
public:
PokemonStation() {};
PokemonStation(int x) {
id = x;
};
int id;
void assigntoList(int i,Pokemon x)
{
if (i > 0)
i--;
list[i] = new Pokemon(x);
cout << "creat" << list[i];
};
};
class PokemonWorld {
private:
char name[10];
public:
PokemonStation s1;
PokemonStation s2;
PokemonWorld() {};
PokemonWorld(char x[], int y=1, int z=2) {
strncpy_s(name, x, 10);
PokemonStation s1(y);
PokemonStation s2(z);
};
const char* const getName() const{
return name;
};
void assigntoStation(int i,Pokemon x) {
if (i == 0 || i % 2 == 0)
s1.assigntoList(i, x);
else
s2.assigntoList(i, x);
};
};
void main() {
int number,hp,i;
char name[10];
cout << "What is the World Name ?" <<endl;
cin >> name;
PokemonWorld world(name);
cout << "Please input the number of Pokemon in the " << world.getName() <<" world:" << endl;
cin >> number;
Pokemon **mon = new Pokemon*[number];
cout << "Please input the characteristics of all Pokemon: Name HP" << endl;
for (i = 0;i < number;i++)
{
cin >> name >> hp;
mon[i] = new Pokemon(name, hp);
world.assigntoStation(i,*(mon[i]));
}
for (i = 0;i < number;i++)
cout << "world is " << world.getName() << endl;
system("pause");
};
In C++, you should use std::vectors for dynamic lists of things and std::strings for text. If you know Java, these are like ArrayList and String. (To use these, make sure you #include <vector> and <string>.)
For instance, your Pokemon class, rewritten with name as a string:
class Pokemon {
public:
Pokemon() {}
Pokemon(string name, int hp):name(name), hp(hp) { // construct the fields directly
}
private:
string name;
int hp;
};
And your PokemonStation class, rewritten using a vector for the list of Pokemon:
class PokemonStation {
private:
vector<Pokemon> list;
public:
PokemonStation() {}
PokemonStation(int x):id(x) {}
int id;
void assignToList(Pokemon x)
{
list.push_back(x); // add x to the list
}
};
If you want to print a Pokemon with cout <<, then you'll have to overload the << operator to define what gets printed. Add this into your class:
class Pokemon {
public:
...
friend ostream& operator<<(ostream& out, const Pokemon& p) {
out << p.name; // just print the name
return out;
}
...
};
Just make sure that you're couting a Pokemon, not a pointer-to-Pokemon (Pokemon*), and you won't get an address.
I dont understand why i am not getting total.
The question is
Define a class student with the following specification:Private
members of class student admno integer sname 20 character eng.
math, science float total float ctotal() a function to calculate eng +
math + science with float return type. Public member function of
class student Takedata() Function Public member function of class
student Takedata() Function float ctotal() a function to calculate
eng + math + science with floa return type. Public member function
of class student Takedata() Function
#include<stdio.h>
#include<iostream>
using namespace std;
class Student
{
private:
int admno;
char sname[20];
float english,maths,science;
float total;
float ctotal()
{
total=(english+maths+science);
return(total);
}
public:
void Takedata()
{
cout<<"Enter the value of admno:";
cout<<" sname :";
cout<<"eng :";
cout<<"science:";
cout<<"maths:";
cin>>admno;
cin>>sname;
cin>>english;
cin>>science;
cin>>maths;
}
Student(): total(0.0) //constructor
{
}
friend float func(Student);
void Showdata()
{
cout<<"adm no:"<<admno;
cout<<"sname:"<<sname;
cout<<"eng"<<english;
cout<<"science"<<science;
cout<<"maths"<<maths;
}
};
float func(Student t)
{
t.total;
return t.total;
}
int main()
{
Student s1;
s1.Takedata();
s1.Showdata();
cout<"total is:";
cout<<func(s1);
}
Need to make either total or method ctotal() public.
Then call either one of them from
public:
float total;
float func(Student t)
{
t.total;
return t.total;
}
OR
public:
float ctotal() {
total=(english+maths+science);
return(total);
}
float func(Student t)
{
return t.ctotal();
}
func should be defind like this
float func(Student t)
{
return t.ctotal();
}
also edit
cout<"total is:";
to
cout<<"total is:";
Replace t.total with t.ctotal() in
float func(Student t)
{
t.total;
return t.total;
}
I don't know how to call my class functions into printData(Testscore&) and readData(TestScore).
Also, could someone tell me why my Average() isn't being called to the main? I just learned about using static member variables and static member functions and was wondering if I am using them incorrectly.
The readData function:
Does not use copy constructor.
Reads all instance variables like the student's names and all their
grades.
Uses functions to store the variables, name, element of each grade of array pointed to private pquiz, and static member
grades of how many grades to read.
The printData function:
Writes the name and average grade of the quizzes.
Uses copy constructor.
This is my program so far:
#include <iostream>
#include <string>
using namespace std;
class TestScore {
private:
static int grades;
string name;
double *pquiz;
double average;
public:
TestScore();
~TestScore();
void setName(string);
static void setGrades(int);
void setPquiz(double *);
void setAverage(double);
string getName();
static int getGrades();
double getPquiz();
void readData(TestScore &);
void printData(TestScore);
double Average(double *, int);
static void Grade(int);
};
TestScore::TestScore() {
name="";
pquiz=new double[grades];
average=0;
}
void TestScore::setName(string name1) {
if(name1!="1") {
name=name1;
}
}
void TestScore::setPquiz(double *pquiz1) {
if(pquiz>=0) {
pquiz=pquiz1;
}
}
void TestScore::setGrades(int grades1) {
if(grades1>=0) {
grades=grades1;
}
}
void TestScore::setAverage(double average1) {
if(average1>=0) {
average=average1;
}
}
string TestScore::getName() {
return name;
}
int TestScore::getGrades() {
return grades;
}
double TestScore::getPquiz() {
return *pquiz;
}
double Average(double *pquiz, int grade) {
int count;
double total=0;
double average=0;
for(count=0; count<grade; count++) {
total+=pquiz[count];
}
average=total/grade;
return average;
}
void readData(TestScore&) {
}
void printData(TestScore) {
}
TestScore::~TestScore() {
delete [] pquiz;
pquiz=0;
}
int TestScore::grades=0;
void TestScore::Grade(int a) {
grades+=a;
}
int main() {
const int grades = 3;
const int students = 4;
TestScore exam;
string student;
int grade;
double *pquiz;
double average;
for(int i=0; i<students; i++) {
cout<<"Student "<<(i+1)<<": ";
cin>>student;
exam.setName(student);
cout<<endl;
for(int count=0; count<grades; count++) {
cout<<"Quiz "<<(count+1)<<": ";
cin>>pquiz[count];
exam.setPquiz(pquiz);
exam.getPquiz();
while(pquiz[count]<0) {
cout<<"Error, invalid test score, please try again."<<endl;
cout<<"Quiz "<<(count+1)<<": ";
cin>>pquiz[count];
}
}
exam.setAverage(average);
cout<<exam.getName()<<" average is "<<Average(pquiz, grade)<<endl<<endl;
}
readData(exam);
printData(exam);
return 0;
}
Don't use static anywhere, at least not for now. You have too many variables of the same name, scattered all over the place. Try to clean them up.
TestScore::TestScore()
{
name = "";
//pquiz = new double[grades];//#grades is undefined
pquiz = NULL;
average = 0;
}
grades is not defined yet, it could be zero, or it could be -817. You should just remove that line, or you can put something like pquiz = new double[10] that's if you are sure the number of quiz will not exceed 10.
TestScore::~TestScore()
{
if (pquiz) delete[] pquiz;
pquiz = NULL;
}
delete pquiz only if it is not NULL
int main() {
const int grades = 3;
const int students = 4;
TestScore exam;
string student;
int grade;
double *pquiz;
...
This is a different pquiz, it is a pointer which points to nothing, it doesn't really exist, you can't use it like that.