Pointer to dynamic array of pointers to objects - c++

Card class header
class card {
public:
string rtn_suit() { return suit; }
int rtn_rank() { return rank; }
void set_suit(string new_suit){ suit = new_suit; }
void set_rank(int new_rank) { rank = new_rank; }
card();
card(string suit, int rank);
card(const card& copyCARD);
~card();
private:
string suit;
int rank;
};
#endif
card.cpp
#include "card.h"
card::card()
{
set_suit("default");
set_rank(0);
}
card::card(string new_suit, int new_rank)
{
// allows for using private class member variables
set_suit(new_suit); // can be anything (string)
set_rank(new_rank); // anticipating simple number ranking (int)
}
card::~card() {}
Deck class header
class deck {
public:
static const int default_cap = 52;
void addCard(card *new_card);
deck & operator=(const deck &sourceDECK);
void deckPrint();
// ----------------------------------------------------
deck(int init_cap = default_cap);
deck(const deck& sourceDECK);
~deck(){ delete [] decklist ; }
private:
card *decklist;
int used;
int capacity;
};
#endif
deck class
deck::deck(int init_cap)
{
card **decklist = new card*[init_cap];
for(int i=0;i<init_cap;i++)
{
decklist[i]=new card;
}
capacity = init_cap;
used=0;
}
deck::deck(const deck& sourceDECK)
{
card **newDECK;
if (capacity != sourceDECK.capacity)
{
newDECK = new card*[sourceDECK.capacity];
for(int i=0;i<sourceDECK.capacity;i++) { newDECK[i]=new card(); }
decklist = /*reinterpret_cast<card*>(*/newDECK/*)*/;
capacity = sourceDECK.capacity;
}
used = sourceDECK.used;
copy(sourceDECK.decklist, sourceDECK.decklist+ used, decklist);
}
deck& deck::operator= (const deck& sourceDECK)
{
if (this == &sourceDECK)
return *this;
card ** newDECK;
if (capacity != sourceDECK.capacity)
{
newDECK = new card*[sourceDECK.capacity];
for(int i=0;i<sourceDECK.capacity;i++) { newDECK[i]=new card(); }
for (int i=0; i<capacity; i++) { delete &decklist[i]; }
delete [ ] decklist;
decklist = /*reinterpret_cast<card*>(*/newDECK/*)*/;
capacity = sourceDECK.capacity;
}
// Copy the data from the source array:
used = sourceDECK.used;
copy(sourceDECK.decklist, sourceDECK.decklist + used, decklist);
return *this;
}
void deck::addCard(card* new_card)
{
//------- Not using vectors----
//deckList.push_back(new_card);
//cout << "Card added."<<endl;
decklist[used] = new_card;
//decklist[used].set_rank(new_card->rtn_rank());
//decklist[used].set_suit(new_card->rtn_suit());
++used;
cout << "Card added."<<endl;
}
void deck::deckPrint()
{
if ( capacity > 0 )
{
for(int i = 0; i < capacity; i++)
{
cout << "----------"<<endl;
cout << decklist[i].rtn_rank() << " ";
cout << decklist[i].rtn_suit() << endl;
cout << "----------"<<endl;
}
}
else\
{
cout << "There are no cards in the deck."<<endl;
}
}
And lastly a main()
int main ()
{
string new_suit, del_suit;
int new_rank, del_rank;
deck newDeck;
card *temp_card;
cout<<"Enter the card's suit: ";
cin>>new_suit;
cout<<endl<<"Enter the card's rank: ";
cin>>new_rank;
cin.clear();
cin.ignore(1000, '\n');
temp_card = new card(new_suit, new_rank);
newDeck.addCard(temp_card);
newDeck.deckPrint();
return 0;
}
Somewhere, somehow I am not initializing or allocating properly. Or maybe I screwed up the pointers....
As is, will not compile due to:
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'card *' (or there is no acceptable conversion)
\projects\cards\cards\card.h(27): could be 'card &card::operator =(const card &)' while trying to match the argument list '(card, card *)'
If I use (currently commented out) a 'deeper copy' aka:
decklist[used].set_rank(new_card->rtn_rnk());
it will throw the error in deckPrint()
I originally wrote this with vectors for a simple card class implementation and then we started learning about dynamic arrays - and I got the bright idea to try and throw pointers in the mix. Again, this is not homework - this is for personal growth.
If there is a tutorial out there that I missed which clearly outlines what I am trying to do, feel free to point me towards that also - I have poured over the top 30 google results and tons of posts here. Half the time people recommend using vectors, which again is not my goal.
Thanks for your time, I know it is lengthy.

I think you have a small bug in your deck class construction function.
deck::deck(int init_cap)
{
card **decklist = new card*[init_cap];
for(int i=0;i<init_cap;i++)
{
decklist[i]=new card;
}
}
here card **decklist is a new pointer to pointer, I guess you want to initialize the private variable decklist.
so you may change it to
deck::deck(int init_cap)
{
decklist = new card*[init_cap];
decklist here is the private variable.
and change the declaration
private:
card **cardlist;

Related

Insert a card into a deck of cards

So i have this program and i want to implement an insert void function. Basically i want to insert a card into the deck. The output should be a deck of cards and the shuffled version and then insert a card and sort it again. How can i accomplish that?
Deck.cpp
#include "deck.h"
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <random>
#include <chrono>
using namespace std;
/**
* Help function to convert Suit enum to string
*/
const string SuitToString(Suit s) {
switch (s) {
case Suit::Hearts:
return "H";
case Suit::Diamonds:
return "D";
case Suit::Spades:
return "S";
case Suit::Clubs:
return "C";
}
return "";
}
Card::Card(int rank, Suit suit)
{
this->rank = rank;
this->suit = suit;
}
/**
* Overload of << operator for Card class
*/
ostream & operator << (ostream &out, const Card &c)
{
string r;
switch(c.rank) {
case 1:
r = 'A';
break;
case 11:
r = 'J';
break;
case 12:
r = 'Q';
break;
case 13:
r = 'K';
break;
default:
r = to_string(c.rank);
break;
}
out << r << SuitToString(c.suit);
return out;
}
/**
* Create a deck of 52 cards
*/
Deck::Deck() {
for (Suit s = Suit::Hearts; s <= Suit::Clubs; s = Suit(s + 1)) {
for (int r=1; r<14; r++) {
cards.push_back(Card(r, s));
}
}
}
/**
* Overload of << operator for Deck class
*/
ostream & operator << (ostream &out, const Deck &d)
{
string separator;
for (auto i: d.cards) {
out << separator << i;
separator = ", ";
}
return out;
}
/**
* Return number of cards in deck
*
*/
int Deck::size()
{
return this->cards.size();
}
/**
* Shuffle all the cards in deck in ranom order.
*/
void Deck::shuffle()
{
auto rng = std::default_random_engine(std::chrono::system_clock::now().time_since_epoch().count());
std::shuffle(this->cards.begin(),this->cards.end(), rng);
}
/**
* Sort the deck according to card rank. All aces, the all two's, then all threes, ...
*/
void Deck::sort()
{
vector<Card> sorted_cards; // Empty temporary deck
while (this->size() > 0) {
// Go through the deck from left to right, insert the deck in the appropriate spot
Deck::insert(sorted_cards, this->take()); //Take a card from the old deck, insert it into the new one
}
this->cards = sorted_cards;
}
/**
* Take the top card from the deck
*/
Card Deck::take() {
Card c = this->cards.back();
this->cards.pop_back();
return c;
}
/**
* Put a card on top of the deck
*/
void Deck::put(Card card) {
cards.push_back(card);
}
void Deck::insert(vector<Card> &cardlist, Card card) {
/**
* My insert code here!
*/
return;
}
Deck.h
#include <iostream>
#include <vector>
#include <string>
using namespace std;
enum Suit {
Hearts,
Diamonds,
Spades,
Clubs
};
class Card
{
private:
int rank;
Suit suit;
public:
Card(int rank, Suit suit);
bool operator == (Card const &other)
{
return rank == other.rank;
}
bool operator < (Card const &other)
{
return rank < other.rank;
}
bool operator > (Card const &other)
{
return rank > other.rank;
}
friend ostream & operator << (ostream &out, const Card &c);
};
class Deck
{
private:
vector<Card> cards;
public:
Deck();
friend ostream & operator << (ostream &out, const Deck &d);
int size();
void shuffle();
void sort();
Card take();
void put(Card card);
static void insert(vector<Card> &cardlist, Card card);
};
main.cpp
#include "deck.h"
#include <iostream>
using namespace std;
main() {
Deck deck = Deck();
cout << "Fresh deck: " << deck << endl;
deck.shuffle();
cout << "Shuffled deck: " << deck << endl;
deck.sort();
cout << "Sorted deck: " << deck << endl;
}
For now i just have written the function itself.
Since Deck::insert is being called from the Deck::sort method, I think the aim is to insert the new card in order with respect to the previously inserted (and therefore already sorted) cards.
So it seems you need something like this
void Deck::insert(vector<Card> &cardlist, Card card) {
// starting from zero
size_t i = 0;
// find the index of the first card in the list that is >= to the card to insert
for (; i < cardList.size(); ++i)
{
if (card < cardList[i])
break;
}
// insert the new card before that index
cardList.insert(cardList.begin() + i, card);
}
This is bad code, for a couple of reasons (efficiency and design) but the above is my take on what you are being asked to do.

initialize member array with constructor

I have a class School like this. Space is an abstract class, don't mind about it.
class school:public space
{
private:
schoolyard y;
stairs s;
floor floors[3];
int capa;
public:
school(int x):floors[1](x),floors[2](x),floors[3](x){
cout<<"a school has been created"<<endl;}
void move(student x);
~school();
};
floor is another class which I want to initialize. This part floors[1](x),floors[2](x),floors[3](x) is probably wrong. Maybe someone know how I can initialize an array of objects in a class?
Should be:
school(int x) : floors{x, x, x}
{
std::cout << "a school has been created" << std::endl;
}
First off, arrays are 0-based, so the valid indexes are 0-2, not 1-3.
Second, you can't initialize individual array members in a constructor's member initialization list like you are attempting to.
If floor does not have a default constructor, you can change your floors[] array to hold floor* pointers instead, and then construct each floor object using new in the constructor's body, eg:
class school : public space
{
private:
...
floor* floors[3];
...
public:
school(int x){
for (int i = 0; i < 3; ++i){
floors[i] = new floor(x);
}
// other initialization as needed...
cout << "a school has been created" << endl;
}
~school(){
for (int i = 0; i < 3; ++i){
delete floors[i];
}
}
...
};
Be aware that with this approach, you need to follow the Rule of 3/5/0, which means also implementing a copy constructor and a copy assignment operator, and optionally a move constructor and a move assignment operation in C++11 and later:
...
#include <algorithm>
class school : public space
{
private:
...
floor* floors[3];
...
public:
school(int x){
for (int i = 0; i < 3; ++i){
floors[i] = new floor(x);
}
// other initializations as needed...
cout << "a school has been created" << endl;
}
school(const school &src){
for (int i = 0; i < 3; ++i){
floors[i] = new floor(*(src.floors[i]));
}
// other copies as needed...
cout << "a school has been copied" << endl;
}
school(school &&src){
for (int i = 0; i < 3; ++i){
floors[i] = src.floors[i];
src.floors[i] = nullptr;
}
// other moves as needed...
cout << "a school has been moved" << endl;
}
~school(){
for (int i = 0; i < 3; ++i){
delete floors[i];
}
}
school& operator=(const school &rhs){
if (this != &rhs){
school temp(rhs);
std::swap_ranges(floors, floors+3, temp.floors);
}
return *this;
}
school& operator=(school &&rhs){
school temp(std::move(rhs));
std::swap_ranges(floors, floors+3, temp.floors);
return *this;
}
...
};
However, a std::vector would make things much easier, letting the compiler handle all of these details for you, eg:
...
#include <vector>
class school : public space
{
private:
...
std::vector<floor> floors;
...
public:
school(int x): floors(3, floor(x)) {
cout << "a school has been created" << endl;
}
...
};

How to initialize an array of user-defined objects with a static ID counter?

Here is my code
#include <iostream>
#include <string>
class Person {
private:
int pancakesEaten, personID;
public:
Person() {
pancakesEaten = 0;
personID = setID();
}
static int setID() {
static int currID;
return currID++; // Returns currID and then increments.
}
bool operator>=(const Person& p);
bool operator<=(const Person& p);
void askPancakesEaten();
void print();
};
bool Person::operator>=(const Person& p) {
if(this->pancakesEaten >= p.pancakesEaten) {
return true;
}
return false;
}
bool Person::operator<=(const Person& p) {
if(this->pancakesEaten <= p.pancakesEaten) {
return true;
}
return false;
}
void Person::askPancakesEaten() {
std::cout << "Please enter how many pancakes you ate: ";
std::cin >> this->pancakesEaten;
}
void Person::print() {
std::cout << this->personID;
std::cout << "Person " << this->personID << " ate " << this->pancakesEaten << " pancakes";
}
int main() {
Person people[10];
for(int i = 0; i<10; i++) {
Person currPerson;
currPerson.askPancakesEaten();
currPerson.print();
}
}
My problem is that I am trying to initialize an array for 10 Person objects, and because of my static method, it is making my static count start at 10 when I enter my for loop.
I know I could get around this easily by just changing my constructor and getting rid of setID and just using i instead, but I am curious if there is another way around it?
... but I am curious if there is another way around it.
Why are you initializing an array and don't use it in the loop then?
for(int i = 0; i<10; i++) {
people[i].askPancakesEaten();
people[i].print();
}
Besides that setID() is named a bit unfortunate confusing (getNextID() might be a better, clearer choice IMO), there's nothing wrong with that implementation as you have it.
Also it would be better to make this function private, since how those ID's are kept and managed to be unique for the class instances, is an implementation detail, which should't be publicly accessible.

C++ Function causing app to crash and not working properly

A problem has come up in my application where my PrintAll function will not work correctly and only ultimately crash my application. My app is supposed to read strings from a file and insert them into an array. The problem is it is reading incorrectly and will ultimately crash my app. Here is where I think the problem lies:
int main()
{
LoadMovies();
MovieList *movies = LoadMovies();
//movies->MovieList::PrintAll();
// // test methods for the Movie and MovieList classes
//PrintAllMoviesMadeInYear(movies, 1984);
//PrintAllMoviesWithStartLetter(movies, 'B');
//PrintAllTopNMovies(movies, 5);
//delete movies;
return 0;
}
MovieList* LoadMovies()
{
vector<string> movies;
ReadMovieFile(movies);
MovieList ml = MovieList(movies.size());
string name;
int year;
double rating;
int votes;
for (int i = 0; i < movies.size(); i++)
{
istringstream input_string(movies[i]);
getline(input_string, name, '\t');
input_string >> year >> rating >> votes;
Movie movie (name, year, votes, rating);
ml.Add(movie);
}
ml.PrintAll();
}
Complete Example:
/*
* File: MovieStatsProgram.cpp
* Author:
* Date:
* ===============================================================
* This is a console app to test the Movie and MovieList classes.
*
* TODO:
*
* You need to finish the implementation of the loadMovies method
* to create and initialize the MovieList object.
*
* You also need to create three static methods:
*
* PrintAllMoviesMadeInYear - it will print all the movies made in a
* given year once sort in alphabetical order and once sorted by the number
* of votes with the movie with the most number of votes printed first.
*
* PrintAllMoviesWithStartLetter - it will print all the movies started with
* a given letter sorted in alphabetical order
*
* PrintAllTopNMovies - it will display the top N movies based on the number of
* votes
*/
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
class Movie {
public:
Movie();
Movie(string n, int y, int v, double r);
string get_name();
void set_name(string n);
int get_year();
void set_year(int y);
int get_votes();
void set_votes(int v);
double get_rating();
void set_rating(double r);
string PrintMovie();
private:
string name;
int year_made;
int votes;
double rating;
};
Movie::Movie() {
name = "null";
year_made = 0;
votes = 0;
rating = 0.0;
}
Movie::Movie(string n, int y, int v, double r) {
name = n;
year_made = y;
votes = v;
rating = r;
}
string Movie::get_name() {
return name;
}
void Movie::set_name(string n) {
name = n;
}
int Movie::get_year() {
return year_made;
}
void Movie::set_year(int y) {
year_made = y;
}
int Movie::get_votes() {
return votes;
}
void Movie::set_votes(int v) {
votes = v;
}
double Movie::get_rating() {
return rating;
}
void Movie::set_rating(double r) {
rating = r;
}
string Movie::PrintMovie() {
cout << fixed << setprecision(1) << rating << "\t\t" << votes << "\t\t" << "(" <<
year_made << ")" << "\t" << name << endl;
}
class MovieList {
public:
MovieList(int size);
~MovieList();
int Length();
bool IsFull();
void Add(Movie const& m);
string PrintAll();
private:
Movie* movies;
int last_movie_index;
int movies_size;
int movie_count = 0;
};
MovieList::MovieList(int size) {
movies_size = size;
movies = new Movie[movies_size];
last_movie_index = -1;
}
MovieList::~MovieList() {
delete [] movies;
}
int MovieList::Length() {
return last_movie_index;
}
bool MovieList::IsFull() {
return last_movie_index == movies_size;
}
void MovieList::Add(Movie const& m)
{
if (IsFull()) {
cout << "Cannot add movie, list is full" << endl;
return;
}
++last_movie_index;
movies[last_movie_index] = m;
}
string MovieList::PrintAll() {
for (int i = 0; i < last_movie_index; i++) {
movies[last_movie_index].Movie::PrintMovie();
//cout << movies[last_movie_index] << endl;
}
}
void ReadMovieFile(vector<string> &movies);
MovieList* LoadMovies();
enum MovieSortOrder
{
BY_YEAR = 0,
BY_NAME = 1,
BY_VOTES = 2
};
int main()
{
LoadMovies();
MovieList *movies = LoadMovies();
//movies->MovieList::PrintAll();
// // test methods for the Movie and MovieList classes
//PrintAllMoviesMadeInYear(movies, 1984);
//PrintAllMoviesWithStartLetter(movies, 'B');
//PrintAllTopNMovies(movies, 5);
//delete movies;
return 0;
}
MovieList* LoadMovies()
{
vector<string> movies;
ReadMovieFile(movies);
MovieList ml = MovieList(movies.size());
string name;
int year;
double rating;
int votes;
for (int i = 0; i < movies.size(); i++)
{
istringstream input_string(movies[i]);
getline(input_string, name, '\t');
input_string >> year >> rating >> votes;
Movie movie (name, year, votes, rating);
ml.Add(movie);
}
ml.PrintAll();
}
void ReadMovieFile(vector<string> &movies)
{
ifstream instream;
instream.open("imdbtop250.txt");
if (instream.fail())
{
cout << "Error opening imdbtop250.txt" << endl;
exit(1);
}
while (!instream.eof())
{
string movie;
getline(instream, movie);
movies.push_back(movie);
}
instream.close();
}
When I use MovieList::PrintAll in the main function, my function just crashes, and when I put it in the LoadMovies function, it will read and add data incorrectly before crashing. The size of the list is 251 and the application will just read the same data 251 times.
You have a two part problem:
1: As Brad S stated, your function returns nothing. This is a no-no.
MovieList* LoadMovies()
{
MovieList ml = MovieList(movies.size());
// Your function returns a pointer to a MovieList, so...
return &ml;
}
So, problem #2 is that you're going to return a pointer to something you created on the stack in your function. When you try to access it outside of your function, you'll run into undefined behavior.
Option 1:
MovieList* ml = new MovieList( movies.size() );
return ml;
You now need to delete ml when you're done w/ it.
Option 2:
Change your function to return a non-pointer... then you don't have the hassle of managing the memory.
EDIT: Try this
int main()
{
// Don't need this
// LoadMovies();
MovieList *movies = LoadMovies();
// Uncommented this
delete movies;
return 0;
}
MovieList* LoadMovies()
{
vector<string> movies;
ReadMovieFile(movies);
// CHANGE
MovieList* ml = new MovieList(movies.size());
// CHANGE
string name;
int year;
double rating;
int votes;
for (int i = 0; i < movies.size(); i++)
{
istringstream input_string(movies[i]);
getline(input_string, name, '\t');
input_string >> year >> rating >> votes;
Movie movie (name, year, votes, rating);
ml.Add(movie);
}
ml.PrintAll();
// CHANGE
return ml;
}
Your MovieList class has a fundamental problem. This comes to light on this line:
MovieList ml = MovieList(movies.size());
Your MovieList class has a member that is a pointer to dynamically allocated memory. Once you have this, you have to manage copying and assignment by creating a user-defined copy constructor and assignment operator.
The easiest fix for this is to use std::vector<Movie> instead of Movie * as a member variable of MovieList. Then copy-assignment comes for free and you don't need to implement further functions.
However, if you can't use std::vector for some reason, the following functions can be added:
class MovieList {
public:
//...
MovieList(const MovieList& m);
MovieList& operator=(MovieList m);
//...
};
#include <algorithm>
//...
// copy constructor
MovieList::MovieList(const MoveList& m) {
movies_size = m.size;
movie_count = m.movie.count;
last_movie_index = m.last_movie_index;
movies = new Movie[movies_size];
for (int i = 0; i < movies_size; ++i)
movies[i] = m.movies[i];
}
//...
// assignment operator
MovieList& MovieList::operator=(MoveList m) {
std::swap(m.movie_size, movie_size);
std::swap(m.last_movie_index, last_movie_index);
std::swap(m.movies, movies);
std::swap(m.movie_count, moviE_count);
return *this;
}
The easiest way to describe this to you is not to describe what these do. The best thing for you is to use your debugger and put a breakpoint in any of these functions and step through the code. When you hit the line I mentioned above, you will more than likely see that the copy constructor function is called -- then you can see it in action as to what it is doing.
The assignment operator is the function that's called when you assign an existing MovieList to another MovieList. It's implemented via the copy/swap idiom. This relies on a working copy constructor (provided above), and a destructor (which you already provided in your code). It works by creating a temporary MovieList, and swapping out the internals of the current MovieList with the temporary MovieList. There are many threads on SO as to how this works.
As to the reason why you need these functions above is that without the above functions, the line:
MovieList ml = MovieList(movies.size());
will create two MovieList objects, one temporary and one non-temporary, however the movies pointer for both will be pointing to the same memory. When the temporary is destroyed, the destructor is called, thus deleting the memory pointed to by movies. Now you have m1 pointing to memory that has gone up in smoke. Bad news when you try to use m1.
The user-defined copy and assignment functions above properly copy the object so that you get two distinct memory allocations for movies, so that when the destructor is called, the memory deleted will be unique to that object.
Again, all of this would be alleviated if you used std::vector and forego having to write copy ctor/assignment operators.

C++ MovieList array and pointer

I'm still a bit stuck on another part on my assignment.
Here is what the prompt is asking:
Now you can modify the LoadMovies function to create a MovieList
object and add each of the Movie objects to it. The function
LoadMovies should return a pointer to the MovieList object. That means
you need to create the MovieList object dynamically and on the heap.
Change the main function and store the returned MovieList pointer in a
variable. To test if everything works as expected, you can use the
PrintAll function of the MovieList object.
Here is my code so far:
class MovieList {
public:
Movie* movies;
int last_movie_index;
int movies_size;
int movie_count = 0;
MovieList(int size) {
movies_size = size;
movies = new Movie[movies_size];
last_movie_index = -1;
}
~MovieList() {
delete [] movies;
}
int Length() {
return movie_count;
}
bool IsFull() {
return movie_count == movies_size;
}
void Add(Movie const& m)
{
if (IsFull())
{
cout << "Cannot add movie, list is full" << endl;
return;
}
++last_movie_index;
movies[last_movie_index] = m;
}
void PrintAll() {
for (int i = 0; i < movie_count; i++) {
movies[last_movie_index].PrintMovie();
}
}
};
void ReadMovieFile(vector<string> &movies);
void LoadMovies();
enum MovieSortOrder
{
BY_YEAR = 0,
BY_NAME = 1,
BY_VOTES = 2
};
int main()
{
LoadMovies();
// TODO:
// You need to implement the Movie and MovieList classes and
// the methods below so that the program will produce
// the output described in the assignment.
//
// Once you have implemented everything, you should be able
// to simply uncomment the code below and run the program.
MovieList *movies = LoadMovies();
// // test methods for the Movie and MovieList classes
//PrintAllMoviesMadeInYear(movies, 1984);
//PrintAllMoviesWithStartLetter(movies, 'B');
//PrintAllTopNMovies(movies, 5);
//delete movies;
return 0;
}
void LoadMovies()
{
vector<string> movies;
ReadMovieFile(movies);
string name;
int year;
double rating;
int votes;
for (int i = 0; i < movies.size(); i++)
{
istringstream input_string(movies[i]);
getline(input_string, name, '\t');
input_string >> year >> rating >> votes;
Movie movie (name, year, votes, rating);
movie.PrintMovie();
}
}
Now where I'm stuck at is where the professor asks me to modify the LoadMovies in the prompt and turn it into a pointer. I'm drawing blanks. Also for some reason if I try to compile it says:
C:\Users\Andy\Documents\C++ Homework\MovieStatisticsProgram\MovieStatsProgram.cpp:163: error: void value not ignored as it ought to be
MovieList *movies = LoadMovies();
^
The order of your constructor is wrong
MovieList(int size) {
movies = new int[movies_size]; // movies_size hasn't been initialized yet!
movies_size = size;
last_movie_index = -1;
}
It should be
MovieList(int size)
: movies_size{size}, movies{new int[size]}, last_movie_index{0}
{}
Though as #ScottMcP-MVP noted your array should be
Movie* movie;
So your constuctor would be
MovieList(int size)
: movies_size{size}, movies{new Movie[size]}, last_movie_index{0}
{}
Some advice for getting started on the remaining functions
Length function will return how many are current used from last_movie_index.
IsFull will check if last_movie_index == movies_size - 1
Add will need to use last_movie_index to figure out what element in your array to store the movie.
PrintAll will have to iterate from [0] to [movie_count] and print out each element.
Your Add function would look something like
void MovieList::Add(Movie const& m)
{
if (IsFull())
{
std::cout << "Cannot add movie, list is full" << std::endl;
return;
}
movies[last_movie_index] = m; // assigns a copy to your array
++last_movie_index; // Increment the movie index
}