Необходимы динамические массивы, деструктор, глубокое копирование

Итак, вот вещи, которые мне еще нужно сделать. У меня возникли серьезные проблемы с синтаксисом. Я не знаю, почему я получаю сообщение об ошибке при попытке объявить динамически размещенный массив. Было бы здорово, если бы я мог получить некоторую помощь по этому вопросу.

BabyNames учебный класс:

  1. Должен иметь в качестве данных членов:
    • динамически распределяемый массив объектов данных
    • элемент данных int, который представляет емкость массива
    • элемент данных int для отслеживания того, сколько мест в массивах содержат объекты данных.
  2. Помимо одного или нескольких «обычных» конструкторов, также реализуйте
    я. конструктор копирования, который выполняет «глубокое» копирование — используйте его для создания копий.
    II. перегруженный оператор присваивания
    III. виртуальный деструктор для освобождения любой памяти, выделенной любым из конструкторов.
  3. Перегрузите вставку (<<) и извлечение (>>) операторы.

Вот шапка

        /*
* File:   BabyNames.h
* Author: jack
*
* Created on March 18, 2013, 3:35 PM
*/

#ifndef BABYNAMES_H_
#define BABYNAMES_H_
#include <string>
#include <fstream>
using namespace std;
using std::ifstream;

/**
* gender: an enum to hold types boy and girl
*/
enum gender {boy, girl};

/**
* PeopleStats: a data struct to hold year, name, double, and the enum type
* gender
*/
struct PeopleStats {
short year;
string name;
double percent;
gender sex;
};

/**
* Names: A class that reads data from a file into a PeopleStats Array
* and is capable of sorting them by name and by popularity percentage
*/
class BabyNames {

public:
BabyNames();
BabyNames(const char fn[], const int numLines);
gender parseSex(string s);
void swap(int i);
const int getCapacity();//getter for dataSize
const PeopleStats& get(int i) const; //getter for objects of the data array
void sortByName();      //Sorts the names alphabetically
void sortByPopularity();//Sorts the names by popularity
friend std::ostream& operator<<(std::ostream& os, const BabyNames& bn);
//friend std::PeopleStats& operator =(const PeopleStats& rhs);

private:
static const int MAX_DATA_SIZE = 25000;
PeopleStats* people;

int capacity;
int fillCount; // to keep track of how many array locations have data objects in them
static const int OUT_OF_BOUNDS = -1;

};//end of class

#endif  /* BABYNAMES_H */

Вот функции

/**
* PeopleSort.cpp
* Description:
* This class stores the information in data structure and includes methods that
* sort the data by name and by popularity.
* Created:
* Feb 27, 2013
* Modified:
* March 1st 2013
*/

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
using std::ifstream;
#include "BabyNames.h"
/**
* BabyNames: A class that reads data from a file into a PeopleStats Array
* and is capable of sorting them by name and by popularity percentage
*/

BabyNames::BabyNames(const char fn[], const int numLines) {
people = new PeoplStats[MAX_DATA_SIZE]; //edit I put this in but I still get errors
//set current capacity
capacity = numLines;
//Open File
ifstream myfile;
myfile.open(fn);
//read in data
int current = 0;
while (current < capacity) {
myfile >> people[current].year;
myfile >> people[current].name;
myfile >> people[current].percent;
string sex;
myfile >> sex;
people[current].sex = parseSex(sex);
current++;
}

}

BabyNames::~BabyNames(){
cout << "Deconstructor" << endl;
delete[]people; //Edit: I added this
}

/*
* sortByName - Sorts the entire array of people by name using the bubble
* sort algorithm. Array is sorted according to name, within the structure
* Algorithm becomes extremely slow if capacity > 3000
*/
void BabyNames::sortByName(){
//sorted is set to true if no changes were made
bool sorted = false;
//change tells the loop if we made a swap or not
bool change = false;
while (!sorted) {
for (int i = 0; i < capacity - 1; i++) {
int compare = people[i].name.compare(people[i + 1].name);
if (compare == 1) {
swap(i);
change = true;
}
}
//if the array was not changed,
//changed sorted to true and exit loop
if (change == false)
sorted = true;
//otherwise reset change and repeat the loop
else
change = false;
}
}

/**
* sortByPopularity - sorts the entire array using the bubble sort algorithm
* Method is almost exactly the same as sortByName, except the compare
* variable is a double consisting of the difference of the two popularity
* percentages.
* Algorithm becomes extremely slow if capacity > 3000
*/
void BabyNames::sortByPopularity(){
bool sorted = false;
bool change = false;
while (!sorted) {
for (int i = 0; i < capacity - 1; i++) {
double compare = people[i].percent - people[i + 1].percent;
if (compare < 0) {
swap(i);
change = true;
break;
}
}
if (change == false)
sorted = true;
change = false;
}
}

/**
* swap - swaps the positions of people[i] and people[i + 1]
* @param i - index of the people array that will get swapped with i + 1
*/
void BabyNames::swap(int i) {
PeopleStats temp = people[i + 1];
people[i + 1] = people[i];
people[i] = temp;
}
/**
* parseSex: extracts the gender from the input and returns the appropriate enum
* @param s
* @return gender object
*/
gender BabyNames::parseSex(string s) {
if (s == "boy")
return boy;
else if (s == "girl")
return girl;
else
throw "invalid Gender";
}

/**
* getCapacity: returns the number of data entries stored.
* @return size of the data
*/
const int BabyNames::getCapacity(){
return capacity;
}
/**
* get: returns one PeopleStat Object
* @param i
* @require: i < capacity
* @return PeopleStat object
*/
const PeopleStats& BabyNames::get(int i) const {
if (i>=0 && i < capacity)
return people[i];
throw OUT_OF_BOUNDS;
}
/**
* << - overloads the outstream operator for PeopleStats object
* @param os
* @param d
* @return os : output stream
*/
std::ostream & operator << (std::ostream& os, const PeopleStats& d){
os << d.name << " " << d.year << " " << d.percent << " " << d.sex;
return os;
}

/**
* <<: overloads the outstream operator for the BabyNames object
* @param os
* @param bn
* @return
*/
std::ostream& operator<<(std::ostream& os, const BabyNames& bn) {
os << "  BabyNames object " << std::endl;
for (int i=0; i < 5000; i++ )
os << "    " << (i+1) <<":  " << bn.get( i ) << std::endl;
return os;
}//end of operator

Вот основной

/*Title: CS 237 Assignment#1

* Created:
* Feb 27, 2013
* Modified:
* March 1st 2013
********************************/

#include <iostream>
#include "BabyNames.h"
/**
* main: The client function that controls the server, BabyNames
* For reasons currently unknown, the program will take forever
* to run after the  * 3000-5000 line mark.
* @return 0 if successful
*/
int main(void) {
cout << "People names: " << endl;
BabyNames names("src/people.txt", 5000 );
cout << names;
cout << "Sorted by popularity" << endl;
names.sortByPopularity();
cout << names;
//    cout << "Sorted by name" << endl;
//    names.sortByName();
//    cout << names;
cout << "... done!" << endl;
return 0;//This is a suggested Main by my professor
/*    cout << "People names: " << endl;
const char filename[] = "src/people.txt";
cout << " 1. Reading file: \"" << filename << "\" ... ";
int number_of_names = checklines( filename );
cout << " number of lines in file is: " << number_of_names;
BabyNames* names = new BabyNames( number_of_names );

// read the contents of a file into names and print them
ifstream file( filename, ios::in );
file >> *names;
cout << " file has been read!" << endl;

// Sort and print
cout << " 2. Sorted by popularity:" << endl;
BabyNames* namesByPop = new BabyNames( *names );
namesByPop->sortByPopularity();
cout << *namesByPop;

// Sort and print
cout << " 3. Sorted by name:" << endl;
BabyNames* namesByName = new BabyNames( *names );
namesByName->sortByName();
cout << *namesByName;

// Sort and print
cout << " 4. Sorted by year:" << endl;
BabyNames* namesByYear = new BabyNames( *names );
namesByYear->sortByYear();
cout << *namesByYear;

cout << " 5. Original names:" << endl;
cout << *names;

delete names;
delete namesByYear;
delete namesByName;
delete namesByPop;*/cout << "... all done!" << endl;

}

Кроме того, файл, который я читаю, имеет много строк, которые выглядят так

1880 John 0.081541 boy
1880 William 0.080511 boy
1880 James 0.050057 boy
1880 Charles 0.045167 boy

2

Решение

Я не думаю, что вижу, где вы на самом деле распределяете память в своем конструкторе.

BabyNames::BabyNames(const char fn[], const int numLines) {
people = new PeopleStats[numLines];
// check for null
.....
}

Также освободите память в своем деструкторе:

BabyNames::~BabyNames() {
delete [] people;
}
1

Другие решения

Я предполагаю, что у вас есть проблемы со следующей строкой в ​​заголовке:

PeopleStats* people = new PeopleStats[MAX_DATA_SIZE];

Вы не можете динамически распределять память в заголовке. Вот почему это не скомпилируется. Вам нужно будет динамически распределять память в файле cpp. Вам просто нужно объявить указатель в заголовке (как вы уже сделали). Затем в конструкторе для класса выделите память, прежде чем пытаться получить к ней доступ.

Заголовок:

class BabyNames {
public:
BabyNames(const char fn[], const int numLines);
~BabyNames();

private:
PeopleStats* people;
};

файл cpp:

BabyNames::BabyNames(const char fn[], const int numLines) {
// dynamicall allocate array
people = new PeopleStats[numLines];

// fill in people array here
}

~BabyNames::BabyNames {
// don't forget to free array or you will have a memory leak
delete [] people;
}
0

По вопросам рекламы [email protected]