2013-03-21 43 views
2

好的,所以这里是我仍然需要做的事情。我有一些严重的语法问题。我不知道当我尝试声明动态分配的数组时,为什么会出现错误。如果我可以得到一些帮助,这将是非常好的。动态数组,析构函数,需要深度复制帮助

BabyNames类:

  1. 应该具有尽可能数据成员:
    • 数据的动态分配对象数组
    • 表示阵列
    • int数据的容量int数据成员成员来跟踪其中有多少个数组对象有数据对象。
  2. 除了一个或多个“常规”构造函数,还实现了 i。一个执行“深层”复制的复制构造函数 - 使用它来制作副本。二, iii。过载的赋值运算符 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 
+1

什么是你的问题? – Nick 2013-03-21 14:13:47

+0

我将如何添加我在顶部列出的一些东西? – Freiermuth 2013-03-21 15:10:11

+1

只是一些提示:1)你没有在你的头文件中定义你的析构函数。 2)不要在头文件中使用'namespace',把它放在''.cpp'文件中。 3)如果你已经声明'using namespace std;'然后'使用std :: ifstream;'是毫无意义的。 4)为什么不使用'list'或'vector'? – Nima 2013-03-21 15:27:20

回答

1

我不认为我看到你在你的构造函数中实际分配内存的地方。

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

此外,免费的析构函数的内存:

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

谢谢这真的有帮助,但我仍然有错误,当我有人=新的PeopleStats [numLines];在构造函数中。此行的多个标记 - 类型'PeoplStats'无法解析 - 'PeoplStats'之前预期的类型说明符''''PeoplStats'之前 - '不能将'int *'转换为'PeopleStats *'赋值 – Freiermuth 2013-03-21 15:23:10

+0

您有一个错字:'PeoplStats'(缺少'e')。 – 2013-03-21 15:45:18

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; 
} 
+0

谢谢这真的有帮助,但我仍然有错误,当我有人=新的PeopleStats [numLines];在构造函数中。前“PeoplStats” - 不能转换“诠释*”到“PeopleStats *”;“” 在该行 多个标记 - 预期 - 之前预期的类型说明符“PeoplStats” - 类型“PeoplStats”无法解析 在任务中 – Freiermuth 2013-03-21 15:20:34