动态数组实现ElectionDistrict类报错:无匹配构造函数初始化ElectionDistrict[]
问题描述
我正在编写一个管理选区选举结果的程序,需要存储选区名称等信息。运行时出现错误:"No matching constructor for initialization of 'ElectionDistrict[]'"。要求不使用vector,仅通过动态数组解决该问题,同时程序需实现选区获胜方判定、结果打印及文件保存功能。
相关代码
#include <iostream> #include <fstream> #include <algorithm> #include <cstring> #include <limits> const int MAX_PARTIES = 10; /* Maximum number of parties*/ class ElectionDistrict { private: char* name; int votersCount; int partiesCount; int* partyVotes; std::string* partyNames; public: ElectionDistrict(const char* name, int voters, int parties) /* Constructor*/ : votersCount(voters), partiesCount(parties) { this->name = new char[strlen(name) + 1]; strcpy(this->name, name); partyVotes = new int[partiesCount]; partyNames = new std::string[partiesCount]; } ~ElectionDistrict() { /*Destructor*/ delete[] name; delete[] partyVotes; delete[] partyNames; } const char* getName() const { return name; } int getVotersCount() const { return votersCount; } int getPartiesCount() const { return partiesCount; } const int* getPartyVotes() const { return partyVotes; } const std::string* getPartyNames() const { return partyNames; } void setPartyVotes(int partyIndex, int votes) { partyVotes[partyIndex] = votes; } void setPartyName(int partyIndex, const std::string& partyName) { partyNames[partyIndex] = partyName; } }; // Function to compare ElectionDistrict objects based on party votes bool compareByPartyVotes(const ElectionDistrict& a, const ElectionDistrict& b) { return a.getPartyVotes()[0] > b.getPartyVotes()[0]; } int main() { std::ofstream outFile("districts.txt"); ElectionDistrict* districts; int numDistricts; std::cout << "Enter the number of districts: "; std::cin >> numDistricts; districts = new ElectionDistrict[numDistricts]; /* right here is the problem*/ for (int i = 0; i < numDistricts; ++i) { char name[100]; int voters, numParties; std::cout << "Enter the name of district " << i + 1 << ": "; std::cin >> name; std::cout << "Enter the number of voters in " << name << ": "; std::cin >> voters; std::cout << "Enter the number of parties in " << name << ": "; std::cin >> numParties; districts[i] = ElectionDistrict(name, voters, numParties); for (int j = 0; j < numParties; ++j) { std::string partyName; int votes; std::cout << "Enter the name of party " << j + 1 << " in " << name << ": "; std::cin >> partyName; std::cout << "Enter the number of votes for " << partyName << " in " << name << ": "; std::cin >> votes; districts[i].setPartyVotes(j, votes); districts[i].setPartyName(j, partyName); } } /*writing the information about each election district and its associated parties to output file (districts.txt)*/ for (int i = 0; i < numDistricts; ++i) { outFile << districts[i].getName() << " " << districts[i].getVotersCount() << " " << districts[i].getPartiesCount(); for (int j = 0; j < districts[i].getPartiesCount(); ++j) { outFile << " " << districts[i].getPartyVotes()[j] << " " << districts[i].getPartyNames()[j]; } outFile << std::endl; } outFile.close(); // Rest of the code remains the same delete[] districts; // Release memory return 0; }
问题分析与解决方案
错误原因
使用new ElectionDistrict[numDistricts]创建动态数组时,C++会为每个数组元素调用类的默认构造函数(无参构造),但当前ElectionDistrict类仅定义了带参数的构造函数,编译器不会自动生成默认构造函数,因此触发编译错误。
此外,类中包含指针成员(char* name、int* partyVotes等),默认的赋值运算符会执行浅拷贝,导致多个对象共享同一块内存,析构时重复释放内存引发崩溃,必须实现拷贝构造函数和赋值运算符重载。
修改步骤
1. 完善ElectionDistrict类
添加默认构造函数、拷贝构造函数、赋值运算符重载,同时新增获胜方判定和结果打印的成员函数:
class ElectionDistrict { private: char* name; int votersCount; int partiesCount; int* partyVotes; std::string* partyNames; public: // 默认构造函数 ElectionDistrict() : name(nullptr), votersCount(0), partiesCount(0), partyVotes(nullptr), partyNames(nullptr) {} // 带参构造函数 ElectionDistrict(const char* name, int voters, int parties) : votersCount(voters), partiesCount(parties) { this->name = new char[strlen(name) + 1]; strcpy(this->name, name); partyVotes = new int[partiesCount]; partyNames = new std::string[partiesCount]; } // 拷贝构造函数(深拷贝) ElectionDistrict(const ElectionDistrict& other) { votersCount = other.votersCount; partiesCount = other.partiesCount; // 拷贝名称 if (other.name) { name = new char[strlen(other.name) + 1]; strcpy(name, other.name); } else { name = nullptr; } // 拷贝政党票数 if (other.partyVotes && partiesCount > 0) { partyVotes = new int[partiesCount]; for (int i = 0; i < partiesCount; ++i) { partyVotes[i] = other.partyVotes[i]; } } else { partyVotes = nullptr; } // 拷贝政党名称 if (other.partyNames && partiesCount > 0) { partyNames = new std::string[partiesCount]; for (int i = 0; i < partiesCount; ++i) { partyNames[i] = other.partyNames[i]; } } else { partyNames = nullptr; } } // 赋值运算符重载(深拷贝) ElectionDistrict& operator=(const ElectionDistrict& other) { if (this == &other) return *this; // 防止自赋值 // 释放当前对象的内存 delete[] name; delete[] partyVotes; delete[] partyNames; // 拷贝成员变量 votersCount = other.votersCount; partiesCount = other.partiesCount; // 拷贝名称 if (other.name) { name = new char[strlen(other.name) + 1]; strcpy(name, other.name); } else { name = nullptr; } // 拷贝政党票数 if (other.partyVotes && partiesCount > 0) { partyVotes = new int[partiesCount]; for (int i = 0; i < partiesCount; ++i) { partyVotes[i] = other.partyVotes[i]; } } else { partyVotes = nullptr; } // 拷贝政党名称 if (other.partyNames && partiesCount > 0) { partyNames = new std::string[partiesCount]; for (int i = 0; i < partiesCount; ++i) { partyNames[i] = other.partyNames[i]; } } else { partyNames = nullptr; } return *this; } ~ElectionDistrict() { /*Destructor*/ delete[] name; delete[] partyVotes; delete[] partyNames; } const char* getName() const { return name; } int getVotersCount() const { return votersCount; } int getPartiesCount() const { return partiesCount; } const int* getPartyVotes() const { return partyVotes; } const std::string* getPartyNames() const { return partyNames; } void setPartyVotes(int partyIndex, int votes) { if (partyIndex >= 0 && partyIndex < partiesCount) { partyVotes[partyIndex] = votes; } } void setPartyName(int partyIndex, const std::string& partyName) { if (partyIndex >= 0 && partyIndex < partiesCount) { partyNames[partyIndex] = partyName; } } // 判定获胜政党 std::string getWinningParty() const { if (partiesCount == 0 || !partyVotes || !partyNames) { return "No parties recorded"; } int maxVotes = -1; int winningIndex = 0; for (int i = 0; i < partiesCount; ++i) { if (partyVotes[i] > maxVotes) { maxVotes = partyVotes[i]; winningIndex = i; } } return partyNames[winningIndex]; } // 打印选区选举结果 void printResults() const { std::cout << "选区名称: " << (name ? name : "未命名") << std::endl; std::cout << "选民总数: " << votersCount << std::endl; std::cout << "参选政党数: " << partiesCount << std::endl; std::cout << "各政党得票情况:" << std::endl; for (int i = 0; i < partiesCount; ++i) { std::cout << " " << partyNames[i] << ": " << partyVotes[i] << " 票" << std::endl; } std::cout << "获胜政党: " << getWinningParty() << "\n" << std::endl; } };
2. 修改main函数
在文件保存后添加结果打印逻辑:
int main() { std::ofstream outFile("districts.txt"); ElectionDistrict* districts; int numDistricts; std::cout << "Enter the number of districts: "; std::cin >> numDistricts; districts = new ElectionDistrict[numDistricts]; // 现在可正常执行 for (int i = 0; i < numDistricts; ++i) { char name[100]; int voters, numParties; std::cout << "Enter the name of district " << i + 1 << ": "; std::cin >> name; std::cout << "Enter the number of voters in " << name << ": "; std::cin >> voters; std::cout << "Enter the number of parties in " << name << ": "; std::cin >> numParties; districts[i] = ElectionDistrict(name, voters, numParties); for (int j = 0; j < numParties; ++j) { std::string partyName; int votes; std::cout << "Enter the name of party " << j + 1 << " in " << name << ": "; std::cin >> partyName; std::cout << "Enter the number of votes for " << partyName << " in " << name << ": "; std::cin >> votes; districts[i].setPartyVotes(j, votes); districts[i].setPartyName(j, partyName); } } // 保存结果到文件 for (int i = 0; i < numDistricts; ++i) { outFile << districts[i].getName() << " " << districts[i].getVotersCount() << " " << districts[i].getPartiesCount(); for (int j = 0; j < districts[i].getPartiesCount(); ++j) { outFile << " " << districts[i].getPartyVotes()[j] << " " << districts[i].getPartyNames()[j]; } outFile << std::endl; } outFile.close(); // 打印所有选区的选举结果 std::cout << "\n===== 选举结果汇总 =====" << std::endl; for (int i = 0; i < numDistricts; ++i) { districts[i].printResults(); } delete[] districts; // 释放内存 return 0; }
说明
- 添加默认构造函数后,动态数组的初始化可正常完成;
- 实现深拷贝的拷贝构造和赋值运算符,避免内存泄漏和重复释放问题;
- 新增
getWinningParty()成员函数遍历得票数据,找出得票最高的政党; - 新增
printResults()成员函数负责打印选区的详细结果; - 保留了原有的文件保存功能,同时添加了结果打印逻辑。
内容的提问来源于stack exchange,提问作者Dodo
相关产品推荐
相关产品推荐

