I'm writing a copy constructor for my class, Vehicle, but I'm having trouble accessing an array that the class has in this constructor. I set other values using dot notation (vehi.vin) and that works fine, as expected. So I tried to access the array using the same idea vehi.accessories[0] but that seems to return a null value rather than the string that's actually there. And I know when I first initialize the class that this array does have the proper values in it because I can print them out. So my question is, how can I access an array from a class? Am I using dot notation wrong? Can I not use dot notation for arrays? Do I just need a get method?
code -
vehicle.cpp
Vehicle::Vehicle(const Vehicle& vehi)
{
//get values and set them equal to the local object's attributes
vin = vehi.vin;
for(int i = 0; i < vehi.numAccessories; i++)
{
//cout << "get here\n";
accessories[i] = vehi.accessories[i];
cout << accessories[i] << " " << vehi.accessories[i] << endl;
}
}
how accessories gets its values:
for(int i = 0; i < numAccessories; i++) //loop through file until all accessories for the car have been put into the array
{
getline(fin, accessories[i]); //put accessory in the next spot in the accessory array
cout << "Accessory " << (i+1) << ": " << accessories[i] << endl;
}
main.cpp declaration of Vehicle object. The constructor reads the values in using the file object passed to it.
Vehicle temp(fin);
vehicle.h
private:
string accessories[50]; //array of accessories stored in string form
Edit: When I try calling the copy constructor directly it works fine but when calling the printVehicle() function it seems to get there but fail somehow. The code below does what I want and shows me that the copy constructor works fine, so I guess it's the way it's invoked from printVehicle()
main.cpp:
Vehicle test(fin);
test.startAcc();
cout << endl << test.nextAcc() << endl;
Vehicle test2(test);
test2.startAcc();
cout << endl << test2.nextAcc() << endl;
Related
I'm extremely new to C++ (even newer to OOP) and I'm doing my first project that doesn't take place within one .cpp file. I've run into a seemingly simple issue where my vector data seems to be disappearing.
Code chunk inside main.cpp's main function:
vector<Horse> HorseStable(horseAmount); // creating an vector of horse objects based on user input horseAmount
for (int i = 0; i < horseAmount; i++) // sets name for each horse and rider
{
string nameString = "";
string riderString = "";
cout << "Enter name for horse #" << (i + 1) << ": ";
cin >> nameString;
HorseStable[i].setName(nameString);
cout << "Enter name for rider of " << nameString << ": ";
cin >> riderString;
HorseStable[i].setRider(riderString);
system("cls");
}
HorseStable[0].printName(); // a test to see if the horse name stayed inside the vector (it did not)
Entire Horse.h file:
#pragma once
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
class Horse
{
private:
std::string name;
std::string rider;
public:
// these three ints were supposed to be private, but I couldn't access
// maxRunningDistPerSecond as a displayHorse() function parameter from main
// maybe figuring out my first issue will help with this, as I was attempting
// HorseStable[0].displayHorse(maxRunningDistPerSecond)
int maxRunningDistPerSecond;
int distanceTraveled;
int racesWon;
Horse() // default constructor
{
std::string name = " ";
std::string rider = " ";
int maxRunningDistPerSecond = 100;
int distanceTraveled = 0;
int racesWon = 0;
};
int runASecond(int, int);
int sendToGate(int);
void displayHorse(int);
std::string setName(std::string); // sets the horse name based on user input from main.cpp variable
std::string printName(); // simply prints the horse name, I don't believe my issue is here
std::string setRider(std::string);
std::string printRider();
};
Code chunk inside Horse.cpp:
std::string Horse::setName(std::string nameString) // takes user input for horse name
{
Horse::name = nameString;
return std::string(nameString);
}
std::string Horse::printName() // prints the horse's name
{
return std::string(name);
}
setName() and getName() work perfectly within my for loop inside main.cpp, but all data seems to disappear when I attempt them after the loop ends. I've looked for hours for solutions, but had to revert to this stable build after nothing worked. I'm not very good with pointers and passing by reference, but these seem to be the only things that will work. Is it possible that I was using pointers wrong? Should I be creating a vector of Horse pointers, rather than a vector of actual Horse objects?
My other issue:
If you've noticed my public members that are supposed to be private in Horse.h, I cannot access them when private as parameters from functions called in main. This makes some sense, as my function call in main looked like this:
HorseStable[0].displayHorse(distanceTraveled)
I'm not sure how I could refer to each element of the vector within the Horse class, which seems like the only way distanceTraveled would be reachable as private. My professor wants the variables in question to be private, which makes this an issue. The user defines the amount of Horse objects, which means I can't just declare a few named Horses and simply displayHorse(distanceTraveled) them.
Function declaration from Horse.cpp:
void Horse::displayHorse(int distanceTraveled) // attempts to show a graphic of the race progress
{
if (distanceTraveled >= 50)
{
std::cout << "|-> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 100)
{
std::cout << "|--> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 150)
{
std::cout << "|---> |" << " " << name << ", ridden by " << rider;
} // this goes on up to 1000, but this is all that's necessary for posting
I apologize if my formatting isn't up to par, but this assignment has really been stressing me out. I've been understanding all the new material, but it always seems like pointers and referencing are the things that render my assignments unusable.
I have such piece of code:
typedef struct reader
{
char name[50];
char card_num[50];
char title[100];
}reader_t;
int main()
{
vector<reader> vec;
ifstream input_file("D:\\lab.txt", ios::binary);
reader_t master[1];
input_file.read((char*)&master, sizeof(master));
for (size_t idx = 0; idx < 1; idx++)
{
reader temp;
strcpy(temp.name, master[idx].name);
strcpy(temp.card_num, master[idx].card_num);
strcpy(temp.title, master[idx].title);
vec.push_back(temp);
cout << "Name: " << master[idx].name << endl;
cout << "Card num: " << master[idx].card_num << endl;
cout << "Title: " << master[idx].title<<endl;
}
cout << vec.size();
getchar();
}
What is does: it reads structures from binary file into an array of structures,copies them into vector and displays structure.And yes, I do need to do like this - I need to store structures from file in vector and this is the only working way to do it I could find(if you can tell, how to read structures to vector directly from file - you are welcome).
So,everything works fine, but the problem is that I need to create a function which would be able to do the same, but with dynamic array.I wrote something like this:
void read_structs(int vec_size)
{
ifstream input_file("D:\\lab.txt", ios::binary);
//Here I commented 2 ways how I tried to create a dynamic array of structs
//reader* master = new reader[vec_size];
//reader* master = (reader*)malloc(sizeof(reader) * vec_size);
input_file.read((char*)&master, sizeof(master));
for (size_t idx = 0; idx < vec_size; idx++)
{
reader temp;
strcpy(temp.name, master[idx].name);
strcpy(temp.card_num, master[idx].card_num);
strcpy(temp.title, master[idx].title);
vec.push_back(temp);
cout << "Name: " << master[idx].name << endl;
cout << "Card num: " << master[idx].card_num << endl;
cout << "Title: " << master[idx].title<<endl;
}
}
And that worked fine too unless I tried to run it.VS wasn't higlighting error in my code, it just was throwing an exception right as the moment when the program tried to access master[0].name.
There is absolutely no point in the temp struct. See, the
vec.push_back(temp);
is already using copy constructor, so copy constructor must work and then the set of strcpy is not doing anything different from that, so just go with
vec.push_back(master[0]).
You can't read into vector directly. You do need to read into temporary. So that is correct. Except I suppose you want to read all entries from the file no matter how many of them there are, so you need to put the read itself also into the loop.
There is not much point in creating an array of one element.
reader_t master[1];
input_file.read((char*)master, sizeof(master));
// ^ you *don't* need & here, arrays degrade to pointers automatically
and
reader_t master;
input_file.read((char *)&master, sizeof(master));
// ^ but you do need & here.
are equivalent. I would go with the later.
So we are basically down to:
reader temp; // calling it temp; the master name makes no sense.
while (input_file.read((char*)&temp, sizeof(temp)))
// read returns input_file and input_file is false if last operation failed
{
vec.push_back(temp);
// verify the stored values by reading back vfrom vec.back().
cout << "Name: " << vec.back().name << endl;
cout << "Card num: " << vec.back().card_num << endl;
cout << "Title: " << vec.back().title<<endl;
}
In the second example, you didn't initialize master, so it obviously crashed.
There is a more C++ approach though. First, you define a read operator for the structure:
std::istream &operator>>(std::istream &in, reader &r) {
return in.read((char *)&r, sizeof(r));
}
and then you simply read the vector using the istream_iterator:
vec.assign(std::istream_iterator<reader>(input_file),
std::istream_iterator<reader>());
and the standard library will generate the above loop for you.
I can start wit hsaying that I'm kind of new to programming.
I got an assigment to create first a class bank account that holds one singel bank account, and also a class Bank that holds all bankaccounts in a vector or array.
One method that had to be included was that it should print out all the accounts in a specific Bank vector.
What I don't understand is what arguments I should pass in to such a method and also how do I call it from the main function where the vector is created.
This is what I've got so far:
void skriv_kontolista(vector <Konto>& nyttKonto)
{
for (unsigned int i = 0; i < nyttKonto.size(); i++)
{
cout << "Konto: " << i << endl;
cout << "Innehavarens kontonummer: " << nyttKonto[i].nummer << endl;
cout << "Innehavarens namn: " << nyttKonto[i].innehavare << endl;
cout << "Innehavarens saldo: " << nyttKonto[i].saldo << endl;
cout << "Innehavarens r\x84ntesats: " << nyttKonto[i].rantesats << endl;
}
}
Is that the right way to do it, and if so, how do I call this method from my main function?
Sorry if my english is bad, it's not my native language.
Thanks in advance.
The code looks OK; it should work. However, this
One method that had to be included was that it should print out all
the accounts in a specific Bank vector.
leads me to believe that skriv_kontolista should be a method in class Bank. Your skriv_kontolista function looks like it's not a method in class Bank (but I don't know for sure).
If indeed it should be a method of class Bank, you should have it in your code like this:
class Bank
{
...
void skriv_kontolista(vector <Konto>& nyttKonto)
{
...
}
...
}
In addition, a method has access to all the fields of the class. One of the fields is the vector that the method must print, so there is no need to send it as a parameter to the function!
class Bank
{
void skriv_kontolista() // no need to have any parameters
{
...
cout << "Innehavarens namn: " << nyttKonto[i].innehavare << endl;
...
}
vector <Konto>& nyttKonto; // a field of the class
}
How to call it from the main function:
int main()
{
Bank bank1, bank2, bank3;
...
bank1.skriv_kontolista();
bank2.skriv_kontolista();
bank3.skriv_kontolista();
}
#include "resistor.h"
void main() {
srand(GetTickCount()); // Lewt's start by seeding the random number generator so that different runs of our program will always yield fifferent results
Resistor * pResistor; // Pointer to a resistor class
int numberOfResistors = 0; // Variable will hold the user choice of the number of resistors to be created
cout << "How many resistors do you want to create?" << endl; // prompt user
cin >> numberOfResistors; // Allow the user to enter the number of resistors to be created
pResistor = new Resistor[numberOfResistors]; // Create an array of objects of class resistor and assign its address to our pointer
// You will notice that there is a logic error here. All the resistors will have the same value. This
// is because they were all created at once. To address this issue we need to create each object
// of the class resistor separately. This means using a loop. This will be up to you to do
// It should be a very easy fix
for (int i = 0; i< numberOfResistors; i++) { // This loop will be used to display the resistor values
cout << "Resistor # " << i + 1 << " has a value of " << pResistor->getResistance() << " " << (char)234 << endl; // Display value of resistor pointed to by pResistor
}
cout << "So far, we have created " << pResistor->getNumerOfResistors() << " resistor(s)" << endl; // Display total number of resistors
delete[] pResistor; // Delete the array that was created and release the memory that was allocated.
} // end of main
I'm am woriking with this code for a class assignment. As you can probably see in the comments there is a logic error that my instructor put in there and I need to fix it. I tried putting the pResistor = new Resistor[numberOfResistors]; line inside a for loop that runs the number of times spcified by user input (instead of creating an array). The problem is still that each object is still created with the same value for ResistorObject.resistance
Any input would be much appreciated
EDIT: The following code is what i tried to explain above:
for (int i = 0; i < numberOfResistors; i++) {
pResistor = new Resistor[i]; // Create an array of objects of class resistor and assign its address to our pointer
}
This however will not compile as I get the error:
error C4703: potentially uninitialized local pointer variable 'pResistor' used
srand(GetTickCount());
Resistor * pResistor = NULL;
vector<Resistor*> resList;
int numberOfResistors = 50; // Use your cin cout here
for (size_t i = 0; i < numberOfResistors; i++)
{
pResistor = new Resistor;
// Assuming some sort of pResistor->SetResistance( /* val */ )
resList.push_back(pResistor);
}
for (int i = 0; i< numberOfResistors; i++) { // This loop will be used to display the resistor values
cout << "Resistor # " << i + 1 << " has a value of " << resList[i]->getResistance() << " " << (char)234 << endl; // Display value of resistor pointed to by pResistor
}
cout << "number of resistors : " << resList.size() << endl;
Each resistor needs its own reference, and all the references must be added to an ordered list. std::vector is used to make ordered lists
I have a C++ vector. I want the vector to hold a variable number of objects.
Visual Studio 2012 is giving me an error:
Error: type name is not allowed
From this C++ code:
#include <iostream>
#include <vector>
using namespace std;
class testObject{
private:
int someInt;
public:
testObject(int a){ someInt=a; }
void show() { cout<<someInt<<endl; }
};
int main()
{
vector<testObject> testVector;
cout << "Initial size: " << testVector.size() <<endl;
for ( int i = 0; i < 3; i++ )
testVector.push_back(testObject(3));
cout << "New size: " << testVector.size() << endl;
for ( int j = 0; j < 3; j++ )
testVector[ j ].show();
system("pause");
}
But here's another sample of code that looks the same but it's not working.
void Dealer::setNumberOfPlayers( const int tNumber )
{
for ( int i = 0; i < tNumber; i++ )
vectorOfGamers.push_back(Player); // Player is a class that I created
}
Can I create vector to hold objects of Dealer, Bot and Player at the same time? How do I do that? As I know, all objects in vector should be of one type.
To answer the first part of your question, you must create an object of type Player before you can use it. When you say push_back(Player), it means "add the Player class to the vector", not "add an object of type Player to the vector" (which is what you meant).
You can create the object on the stack like this:
Player player;
vectorOfGamers.push_back(player); // <-- name of variable, not type
Or you can even create a temporary object inline and push that (it gets copied when it's put in the vector):
vectorOfGamers.push_back(Player()); // <-- parentheses create a "temporary"
To answer the second part, you can create a vector of the base type, which will allow you to push back objects of any subtype; however, this won't work as expected:
vector<Gamer> gamers;
gamers.push_back(Dealer()); // Doesn't work properly!
since when the dealer object is put into the vector, it gets copied as a Gamer object -- this means only the Gamer part is copied effectively "slicing" the object. You can use pointers, however, since then only the pointer would get copied, and the object is never sliced:
vector<Gamer*> gamers;
gamers.push_back(new Dealer()); // <-- Allocate on heap with `new`, since we
// want the object to persist while it's
// pointed to
Question 1:
vectorOfGamers.push_back(Player)
This is problematic because you cannot directly push a class name into a vector.
You can either push an object of class into the vector or push reference or pointer to class type into the vector. For example:
vectorOfGamers.push_back(Player(name, id))
//^^assuming name and id are parameters to the vector, call Player constructor
//^^In other words, push `instance` of Player class into vector
Question 2:
These 3 classes derives from Gamer. Can I create vector to hold objects of Dealer, Bot and Player at the same time? How do I do that?
Yes you can. You can create a vector of pointers that points to the base class Gamer.
A good choice is to use a vector of smart_pointer, therefore, you do not need to manage pointer memory by yourself. Since the other three classes are derived from Gamer, based on polymorphism, you can assign derived class objects to base class pointers. You may find more information from this post: std::vector of objects / pointers / smart pointers to pass objects (buss error: 10)?
You cannot insert a class into a vector, you can insert an object (provided that it is of the proper type or convertible) of a class though.
If the type Player has a default constructor, you can create a temporary object by doing Player(), and that should work for your case:
vectorOfGamers.push_back(Player());
I know the thread is already all, but as I was checking through I've come up with a solution (code listed below). Hope it can help.
#include <iostream>
#include <vector>
class Box
{
public:
static int BoxesTotal;
static int BoxesEver;
int Id;
Box()
{
++BoxesTotal;
++BoxesEver;
Id = BoxesEver;
std::cout << "Box (" << Id << "/" << BoxesTotal << "/" << BoxesEver << ") initialized." << std::endl;
}
~Box()
{
std::cout << "Box (" << Id << "/" << BoxesTotal << "/" << BoxesEver << ") ended." << std::endl;
--BoxesTotal;
}
};
int Box::BoxesTotal = 0;
int Box::BoxesEver = 0;
int main(int argc, char* argv[])
{
std::cout << "Objects (Boxes) example." << std::endl;
std::cout << "------------------------" << std::endl;
std::vector <Box*> BoxesTab;
Box* Indicator;
for (int i = 1; i<4; ++i)
{
std::cout << "i = " << i << ":" << std::endl;
Box* Indicator = new(Box);
BoxesTab.push_back(Indicator);
std::cout << "Adres Blowera: " << BoxesTab[i-1] << std::endl;
}
std::cout << "Summary" << std::endl;
std::cout << "-------" << std::endl;
for (int i=0; i<3; ++i)
{
std::cout << "Adres Blowera: " << BoxesTab[i] << std::endl;
}
std::cout << "Deleting" << std::endl;
std::cout << "--------" << std::endl;
for (int i=0; i<3; ++i)
{
std::cout << "Deleting Box: " << i+1 << " (" << BoxesTab[i] << ") " << std::endl;
Indicator = (BoxesTab[i]);
delete(Indicator);
}
return 0;
}
And the result it produces is:
Objects (Boxes) example.
------------------------
i = 1:
Box (1/1/1) initialized.
Adres Blowera: 0xdf8ca0
i = 2:
Box (2/2/2) initialized.
Adres Blowera: 0xdf8ce0
i = 3:
Box (3/3/3) initialized.
Adres Blowera: 0xdf8cc0
Summary
-------
Adres Blowera: 0xdf8ca0
Adres Blowera: 0xdf8ce0
Adres Blowera: 0xdf8cc0
Deleting
--------
Deleting Box: 1 (0xdf8ca0)
Box (1/3/3) ended.
Deleting Box: 2 (0xdf8ce0)
Box (2/2/3) ended.
Deleting Box: 3 (0xdf8cc0)
Box (3/1/3) ended.
// create a vector of unknown players.
std::vector<player> players;
// resize said vector to only contain 6 players.
players.resize(6);
Values are always initialized, so a vector of 6 players is a vector of 6 valid player objects.
As for the second part, you need to use pointers.
Instantiating c++ interface as a child class