Create Multiple Objects in a loop c++ - c++

I'm a beginner and was researching to find out if you can grab a name from an array to then put that name as the name of the object in a for loop.
The code a specifically created for this question is represented below:
#include <iostream>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
for(int i = 0; i < 4; i++) {
YourMum names[i];
cout << names[i].name << endl;
cout << "You are great if you answer my question!";
}
return 0;
}

Okay, it's not clear what you're trying to do, but you've got a few things that aren't a good idea.
First, you defined string names[5] and then inside loop you hid names by making a second variable with the same name. While that's legal, it's a bad practice.
Second, you're using the second one (YourMum names) illegally:
You declared it as length i (using a non-standard feature of the compiler) but then reference element i. The elements of an array of length i range from 0..i-1, so [i] is one element past the end.
And you haven't initialized it anyway.
I'm not really clear what you're trying to do, so I can't even provide example code of how to do it.

The YourMum class you have shown is not default constructible, so YourMum names[size]; will not work. Every object of YourMum needs to be passed a parameter in order to create it. You can use placement-new for that, eg:
#include <iostream>
#include <type_traits>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
std::aligned_storage<sizeof(YourMum), alignof(YourMum)>::type arr[5];
YourMum *mums = reinterpret_cast<YourMum*>(arr);
for(int i = 0; i < 5; i++) {
new (&mums[i]) YourMum(names[i]);
}
for(int i = 0; i < 5; i++) {
cout << mums[i].name << endl;
cout << "You are great if you answer my question!";
}
for(int i = 0; i < 5; i++) {
mums[i].~YourMum();
}
return 0;
}
Or, you can use std::vector instead:
#include <iostream>
#include <vector>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
std::vector<YourMum> mums;
mums.reserve(5);
for(int i = 0; i < 5; i++) {
mums.emplace_back(names[i]);
}
for(int i = 0; i < 5; i++) {
cout << mums[i].name << endl;
cout << "You are great if you answer my question!";
}
return 0;
}

First of all, you should rename the name variable to something like _name or name_ for lisibility (to differenciate it from variables that aren't in the class), and you should also use the private section of your class to declare it and use getters/setters functions to edit it. Secondly, in your code you are declaring the object inside a loop, so it will get destroyed as soon as the loop iterates again, so if you want to create n objects in a loop and interact with them after you should either use a container class (like std::vector) or use a default constructor (which is better). Here is an updated version of your code:
#include <iostream>
#include <string>
class YourMum
{
public:
YourMum(void) : _name() { }
YourMum(std::string name) : _name(name) { }
std::string getName(void) const { return _name; }
void setName(std::string name) { _name = name; }
private:
std::string _name;
};
int main()
{
std::string names[5] = { "Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum" };
YourMum mums[5];
for (int i = 0; i < 5; i++)
{
mums[i].setName(names[i]);
std::cout << mums[i].getName() << std::endl
<< "You are great if you answer my question!" << std::endl;
}
// this way you can still access mums here if you want to
return 0;
}
If you want to access to a class by it's name as index what you can also do is using std::map like this
#include <map>
int main()
{
std::string names[5] = { "Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum" };
std::map <std::string, YourMum> mums;
for (int i = 0; i < 5; i++)
mums[names[i]] = YourMum(names[i]);
std::cout << mums["Jeremy_Clarkson"].getName() << std::endl;
return 0;
}

Try This
> for(int i = 0; i < 4; i++) {
> YourMum name(names[i]);
>
> cout << name.name << endl;
> cout << "You are great if you answer my question!";
> }

Related

How to pass parameters in an objects of array? in c++

class A
{
int id;
public:
A (int i) { id = i; }
void show() { cout << id << endl; }
};
int main()
{
A a[2];
a[0].show();
a[1].show();
return 0;
}
I get an error since there is no default constructor.However thats not my question.Is there a way that ı can send parameters when defining
A a[2];
A good practice is to declare your constructor explicit (unless it defines a conversion), especially if you have only one parameter. Than, you can create new objects and add them to your array, like this :
#include <iostream>
#include <string>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
A first(3);
A second(4);
A a[2] = {first, second};
a[0].show();
a[1].show();
return 0;
}
However, a better way is to use vectors (say in a week you want 4 objects in your array, or n object according to an input). You can do it like this:
#include <iostream>
#include <string>
#include <vector>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
std::vector<A> a;
int n = 0;
std::cin >> n;
for (int i = 0; i < n; i++) {
A temp(i); // or any other number you want your objects to initiate them.
a.push_back(temp);
a[i].show();
}
return 0;
}

Read access violation?

I am writing some C++ code to create an item of a class i have created inside a vector of another class. I seem to be able to create the items inside the vector but when i try to read a variable of the item inside the vector i get the error
Exception thrown: read access violation.
_Right_data was 0x8.
inside the document xstring.
I think it might have something to do with me not actually creating each team inside the vector.
the code i have written that is relavent is
for (int x = 1; x <= mainLeague.getNumTeams(); x++) {
std::cout << "please enter the name of team " << x << ":";
std::getline(std::cin, currLine);
parsed = parseText(currLine, &posResponsesTeamNames);
if (parsed == 2) {
prepForEnd();
return 1;
}
else if (parsed == 0) goto enterTeamNames;
mainLeague.createTeam(currLine);
}
std::cout << mainLeague.getName(5);
}
#pragma once
#include "team.h"
#include <string>
#include <vector>
#include <iostream>
class league
{
std::vector<team*> teams;
int numTeams, numInitTeams = 0;
const float sysCon = 0.5;
public:
league(int a);
int getNumTeams();
void initVector(int numTeams);
void createTeam(std::string name);
std::string getName(int num);
};
void league::createTeam(std::string name)
{
if (numInitTeams < teams.size()) {
team currTeam = team::team(name);
teams.at(numInitTeams) = &currTeam;
numInitTeams;
}
else {
std::cout << "error max amount of teams already created";
}
}
#pragma once
#include<string>
class team
{
float RD;
int rating;
std::string name;
public:
team(std::string name);
team();
std::string getName();
};
std::string team::getName()
{
return team::name;
}

Why the number of grades is 0?

#include<iostream>
#include<string>
using namespace std;
class Student {
public:
const int codeStud;
int noGrades = 0;
int* grades = NULL;
Student(int code) :codeStud(code) {
}
Student(int code, int* grades, int noGrades) :codeStud(code) {
this->noGrades = noGrades;
this->grades = new int[noGrades];
for (int i = 0; i < noGrades; i++)
this->grades[i] = grades[i];
}
Student(const Student&existent):codeStud(existent.codeStud) {
this->noGrades = existent.noGrades;
this->grades = new int[this->noGrades];
for (int i = 0; i < this->noGrades; i++)
this->grades[i] = existent.grades[i];
}
int getCode() {
return this->codeStud;
}
int getNoGrades() {
return this->noGrades;
}
void setGrades(int grades[],int noGrades) {
this->noGrades = noGrades;
this->grades = new int[noGrades];
for (int i = 0; i < noGrades; i++)
this->grades[i] = grades[i];
}
};
void main() {
Student s1(101);
cout<<s1.getNoGrades();
int grades[] = { 10,7,8,10,4 };
Student s2(104, grades, 5);
cout << "\n" << s2.getNoGrades();
Student s3 = s2;
cout << "\n" << s3.getCode();
int grades2[] = { 5,5,4,10 };
s1.setGrades(grades2,4);
cout << "\n" << s1.getNoGrades(); // here is the problem
}
After I changed the grades for student 1 it shows that he has 0 grades, when the output should be 4, the number of these grades: 5,5,4,10.
The rest of output is correct, even when I want to know the number of grades for student 1, which is 0 , and then for student 2, which is 5.
I've changed some things in your code to compile it
#include<iostream>
#include<string>
using namespace std;
class Student {
public:
int codeStud;
int noGrades = 0;
int* grades = NULL;
Student(int code) {
codeStud = code;
}
Student(int code, int* grades, int noGrades) {
this->noGrades = noGrades;
this->grades = new int[noGrades];
for (int i = 0; i < noGrades; i++)
this->grades[i] = grades[i];
}
Student(const Student&existent){
this->noGrades = existent.noGrades;
this->grades = new int[this->noGrades];
for (int i = 0; i < this->noGrades; i++)
this->grades[i] = existent.grades[i];
}
int getCode() {
return this->codeStud;
}
int getNoGrades() {
return this->noGrades;
}
void setGrades(int grades[],int noGrades) {
this->noGrades = noGrades;
this->grades = new int[noGrades];
for (int i = 0; i < noGrades; i++)
this->grades[i] = grades[i];
}
};
int main() {
Student s1(101);
cout<<s1.getNoGrades();
int grades[] = { 10,7,8,10,4 };
Student s2(104, grades, 5);
cout << "\n" << s2.getNoGrades();
Student s3 = s2;
int grades2[] = { 5,5,4,10 };
s1.setGrades(grades2,4);
cout << "\n" << s1.getNoGrades(); // here is the problem
}
and output is:
0
5
4
what is correct, because you don't assign number of grades of s1 anywhere in your code before first printing
Also look for:
https://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c
why void main() is not correct
After I corrected the typo (codStud --> codeStud) your code produced the correct results for me. Before I did that I couldn't even compile it, so my guess would be that your IDE just run the latest working version of it that could be compiled successfully (look for error messages somewhere). That's the reason you got the wrong result, because your changes weren't even in that version.
A couple of note about your code:
In your setGrades function check that grades not pointing to something already. For example, if I call Student(int code, int* grades, int noGrades) and after I call setGrades your code leaks memory because it loses the array that Student(int code, int* grades, int noGrades) allocated before.
You should use vector instead of C-style arrays. It will make your code much more cleaner and less error-prone (see my example).
You could make your getter functions to const (like in my example), so it would be guaranteed that those functions don't change the value of any member of the class (you get a compile error if they do). Other than that, you can make the member variables to private.
Implementation using vectors:
#include <iostream> // cout
#include <vector> // vector
using namespace std;
class Student
{
public:
Student(const int code)
: m_code{code}
{
}
Student(const int code, const std::vector<int>& grades)
: m_code{code},
m_grades{grades}
{
}
// Default copy constructor is sufficient because the class can be copied
// memberwise.
int getCode() const {
return m_code;
}
int getNoGrades() const {
return m_grades.size();
}
void setGrades(const std::vector<int>& grades) {
m_grades = grades;
}
private:
const int m_code;
std::vector<int> m_grades;
};
int main()
{
Student s1(101);
cout << s1.getNoGrades();
Student s2(104, {10, 7, 8, 10, 4});
cout << "\n" << s2.getNoGrades();
Student s3 = s2;
cout << "\n" << s3.getCode();
s1.setGrades({5, 5, 4, 10});
cout << "\n" << s1.getNoGrades();
return 0;
}

problem passing array of struct to a function throwing undefined reference c++

I'm having issues with passing an array of structures to a function that searches them. I delcare an array of structs outside of main then copy it to a new array of structs inside of main (so I have access to them inside main and can pass them easier). Not sure why it is failing though. Can anyone help me?
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <algorithm>
using namespace std;
const int MAX = 2000000;
const string DFile = "DFile.dms";
const string EFile = "EFile.dms";
const string VFile = "VFile.dms";
struct dogs
{
int did;
int age;
} DFBuffer[MAX];
struct examine
{
int vid;
int did;
int fee;
} EFBuffer[MAX];
struct vet
{
int vid;
int eLevel;
} VFBuffer[MAX];
void readDF(ifstream&);
void readEF(ifstream&);
void readVF(ifstream&);
int getLineCount(ifstream&);
bool dogCompare(dogs lhs, dogs rhs) {return lhs.did < rhs.did;}
bool vetCompare(vet lhs, vet rhs) {return lhs.vid < rhs.vid;}
bool examCompare(examine lhs, examine rhs) {return lhs.vid < rhs.vid;}
void vetExamSeach(struct vet newVetArray[], struct examine newExamArray[],
int, int);
int main()
{
dogs * newDogArray = new dogs[MAX];
examine * newExamArray = new examine[MAX];
vet * newVetArray = new vet[MAX];
ifstream DF, EF, VF;
int dogCount = 0, examCount = 0, vetCount = 0;
DF.open(DFile);
readDF(DF);
EF.open(EFile);
readEF(EF);
VF.open(VFile);
readVF(VF);
DF.open(DFile);
dogCount = getLineCount(DF);
EF.open(EFile);
examCount = getLineCount(EF);
VF.open(VFile);
vetCount = getLineCount(VF);
for(int i = 0; i < dogCount; i++)
newDogArray[i] = DFBuffer[i];
for(int i = 0; i < vetCount; i++)
newVetArray[i] = VFBuffer[i];
for(int i = 0; i < examCount; i++)
newExamArray[i] = EFBuffer[i];
cout << "Sorting...\n";
sort(newDogArray, newDogArray + dogCount, dogCompare);
sort(newExamArray, newExamArray + examCount, examCompare);
sort(newVetArray, newVetArray + vetCount, vetCompare);
cout << "Sorting complete!\n";
vetExamSeach(newVetArray, newExamArray, vetCount, examCount);
return 0;
}
here is the search function. for the sake of this question, im just trying to print what i pass it.
void search(vet newVetArray[], examine newExamArray[], int vCount, int eCount)
{
for(int i = 1; i < vCount; i++)
cout << "in search: " << newVetArray[i].vid << ' ' << newVetArray[i].eLevel << endl;
}
here is the error I'm getting
Here is my files. Not asking you to do my HW just help me solve my issue
When, I run your code, I get the same compilation error of undefined reference for readDf, readEF, readVF, getLineCount and vetExamSeach.
The error is because there is no definition of these functions. There are only just decalarations. When I define them (something random) the errors are gone.
So, define the function(s) and the error(s) would be gone.

C++ Insertion Sort a vector

I'm trying to do an insertion sort on a vector of baseball pitchers I created yesterday with help from a previous post. I want to sort the pitchers in ascending order by ERA1. I have gotten the insertion sort to work in the past for a set of integers. I think I have a syntax error in my code for the insertion sort. Up until trying to add the insertion sort this program was working well. I get an error - expected unqualified id before [ token. Thanks in advance for any help.
#ifndef Pitcher_H
#define Pitcher_H
#include <string>
#include <vector>
using namespace std;
class Pitcher
{
private:
string _name;
double _ERA1;
double _ERA2;
public:
Pitcher();
Pitcher(string, double, double);
vector<Pitcher> Pitchers;
string GetName();
double GetERA1();
double GetERA2();
void InsertionSort(vector<Pitcher>&);
~Pitcher();
};
#endif
#include "Pitcher.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
Pitcher::Pitcher()
{
}
Pitcher::~Pitcher()
{
}
string Pitcher::GetName()
{
return _name;
}
Pitcher::Pitcher(string name, double ERA1, double ERA2)
{
_name = name;
_ERA1 = ERA1;
_ERA2 = ERA2;
}
double Pitcher::GetERA1()
{
return _ERA1;
}
double Pitcher::GetERA2()
{
return _ERA2;
}
#include "Pitcher.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
void InsertionSort(vector<Pitcher> Pitchers&);
using namespace std;
int main()
{
vector<Pitcher> Pitchers;
cout << "Pitcher" << setw(19) << "Item ERA1" << setw(13) <<
"Item ERA2\n" << endl;
Pitcher h2("Bob Jones", 1.32, 3.49);
Pitchers.push_back(h2);
Pitcher h3("F Mason", 7.34, 2.07);
Pitchers.push_back(h3);
Pitcher h1("RA Dice", 0.98, 6.44);
Pitchers.push_back(h1);
for(unsigned i = 0; i < Pitchers.size(); ++i)
{
cout << setw(19);
cout << left << Pitchers[i].GetName() << "$" <<
setw(10) << Pitchers[i].GetERA1() <<
right << "$" << Pitchers[i].GetERA2() << "\n";
}
cout << endl;
//------------------------------------------------------
InsertionSort(Pitchers);
//Now print the numbers
cout<<"The numbers in the vector after the sort are:"<<endl;
for(int i = 0; i < Pitchers.size(); i++)
{
cout<<Pitchers[i].GetERA1()<<" ";
}
cout<<endl<<endl;
system("PAUSE");
return 0;
}
void InsertionSort(vector<Pitcher> &Pitchers)
{
int firstOutOfOrder = 0;
int location = 0;
int temp;
int totalComparisons = 0; //debug purposes
for(firstOutOfOrder = 1; firstOutOfOrder < Pitchers.size() ; firstOutOfOrder++)
{
if(Pitcher.GetERA1([firstOutOfOrder]) < Pitcher.GetERA1[firstOutOfOrder - 1])
{
temp = Pitcher[firstOutOfOrder];
location = firstOutOfOrder;
do
{
totalComparisons++;
Pitcher.GetERA1[location] = Pitcher.GetERA1[location - 1];
location--;
}while(location > 0 && Pitcher.GetERA1[location - 1] > temp);
Pitcher.GetERA1[location] = temp;
}
}
cout<<endl<<endl<<"Comparisons: "<<totalComparisons<<endl<<endl;
}
Here:
for(firstOutOfOrder = 1; firstOutOfOrder < Pitchers.size() ; firstOutOfOrder++)
{
if(Pitchers[firstOutOfOrder].GetERA1() < Pitchers[firstOutOfOrder-1].GetERA1())
{ //^^^your way was not right, should first access the object then
//access member function
temp = Pitcher[firstOutOfOrder];
//^^^should be Pitchers, similar errors below
location = firstOutOfOrder;
do
{
totalComparisons++;
Pitcher.GetERA1[location] = Pitcher.GetERA1[location - 1];
//^^^similar error as inside if condition
location--;
}while(location > 0 && Pitcher.GetERA1[location - 1] > temp);
//^^^similar error as inside if condition
Pitcher.GetERA1[location] = temp;
//^^similar error as in if condition and name error
}
}
Meanwhile, you put the InsertionSort declaration as a member of the Pitcher class
public:
.
.
void InsertionSort(vector<Pitcher>&);
and you also declare the same function inside main,
void InsertionSort(vector<Pitcher> Pitchers&);
//should be vector<Pitcher>& Pitchers
using namespace std;
int main()
the member function probably should be removed in your case. InsertionSort is not a responsibility of your Pitcher class.
Unless this is homework, you're better off using the build in sort from
<algorithm>