2

さて、ここに私がまだやらなければならないことがあります。構文に重大な問題があります。動的に割り当てられた配列を宣言しようとすると、なぜエラーが発生するのかわかりません。これについて少しでもお役に立てれば幸いです。

BabyNamesクラス:

  1. データ メンバーとして以下が必要です。
    • 動的に割り当てられた Data オブジェクトの配列
    • 配列の容量を表す int データ メンバー
    • Data オブジェクトが含まれる配列の場所の数を追跡するための int データ メンバー。
  2. 1 つ以上の「通常の」コンストラクタに加えて、i も実装します。「ディープ」コピーを実行するコピー コンストラクター - これを使用してコピーを作成します。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
4

2 に答える 2

1

コンストラクターのどこに実際にメモリーを割り当てているのかわかりません。

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

また、デストラクタのメモリを解放します。

BabyNames::~BabyNames() {
    delete [] people;
}
于 2013-03-21T14:28:14.900 に答える
0

ヘッダーの次の行に問題があると想定しています。

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;
}
于 2013-03-21T14:36:31.037 に答える