c++ - 需要动态数组、析构函数、深度复制帮助

标签 c++ arrays dynamic deep-copy

好的,下面是我还需要做的事情。我在语法方面遇到了一些严重的问题。我不知道为什么在尝试声明动态分配的数组时会出现错误。如果我能在这方面得到一些帮助,那就太好了。

BabyNames类:

  1. 作为数据成员应该有:
    • 动态分配的数据对象数组
    • 一个表示数组容量的int数据成员
    • 一个 int 数据成员,用于跟踪有多少数组位置包含数据对象。
  2. 除了一个或多个“常规”构造函数外,还实现 我。执行“深”复制的复制构造函数——使用它来制作拷贝。 二.重载的赋值运算符 三.一个虚拟析构函数,用于释放由任何构造函数分配的任何内存。
  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

最佳答案

我想我没有看到您在构造函数中实际分配内存的位置。

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

此外,释放析构函数中的内存:

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

关于c++ - 需要动态数组、析构函数、深度复制帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15549929/

相关文章:

ios - 如何使用 Swift 动态访问数组中的项目

c - C 中的动态内存分配和多级数组

C 编程 printf 从一个数组

java - (Java) 打印出 application.class@xxxxxxx 的数组元素

javascript:如何使用函数式编程比较两个对象数组?

c++ - 为什么将 std::endl 与 ostringstream 一起使用会影响输出速度?

android - 有一个具有默认高度的 ImageView,当将图像放入其中时更改高度

C++ 指向 struct 新数组的指针到 delphi 到 DLL 函数

c++ - 使用聚合初始化初始化数组成员

c++ - 忽略语法错误