我最近开始使用C ++进行文件结构化,但收效甚微。该项目分为以下文件
-groups.h
-groups.cpp
-people.h
-people.cpp
-main.cpp
有两个基类,groups
和players
以及其中任何一个继承的其他类。
这是文件
#ifndef GROUPS_H
#define GROUPS_H
//Groups of people one of the base classes
class groups {
int num_of_people;
float avg_age;
friend class SoccerTeams;
public:
//virtual string getclass() { return char2str(typeid(*(this)).name()); }
groups(int numb = 0): num_of_people(numb) {};
~groups(){};
};
//SoccerTeam group class
class SoccerTeams : public groups {
std::string teamName;
std::vector<SoccerTeams> teams;
int teamId;
public:
Players player;
void addManager();
std::string nameTeam(int);
void deletePlayer(int);
void showTeam();
void addPlayer();
void showPlayers();
void showManagers();
void exportToFile(const char *);
SoccerTeams() {};
SoccerTeams(std::string, int);
~SoccerTeams() {};
};
//FanClub group class
class FanClubs : public groups{
std::string clubName;
int clubId;
std::vector<FanClubs> fanclubs;
public:
Fans fan;
void addFans();
void showFans();
FanClubs() {};
FanClubs(std::string, int);
~FanClubs() {};
};
#endif
#include <algorithm>
#include <iostream>
#include <vector>
#include <typeinfo>
#include <boost/units/detail/utility.hpp>
#include <cstdlib>
#include <fstream>
#include <list>
#include "groups.h"
using namespace std;
//Fan Club member functions
FanClubs::FanClubs(string name, int id) {
clubName = name;
clubId = id;
fanclubs.push_back(*this);
};
void FanClubs::showFans() {
cout << "Players in " << fanclubs.begin() -> clubName << endl;
fan.showFanas();
}
void FanClubs::addFans() {
int choice = 0;
cout << "1. Add a bunch of fans\n2. Add custom fans\nChoice: ";
cin >> choice;
switch(choice) {
case 1: {
int requirement;
cout << "How many fans do you need: ";
cin >> requirement;
static const string names[] = {
"Margarita", "Amalia", "Sam", "Mertie", "Jamila", "Vilma",
"Mazie", "Margart", "Lindsay", "Kerstin", "Lula", "Corinna", "Jina",
"Jimmy", "Melynda", "Demetrius", "Beverly", "Olevia", "Jessika",
"Karina", "Abdallah", "Max", "Prateek", "Aghaid"
};
for (int i = 0; i < requirement; ++i) {
fan.name = names[rand() % 24];
fan.age = (rand() % 80 + 1);
fan.sex = ((rand() % 2) ? 'M' : 'F');
fan.under_auth = false;
fan.auth_level = 0;
fans.push_back(fan);
}
break;
}
case 2: {
int requirement;
cout << "How many fans you want to add?\nnumber: ";
cin >> requirement;
for (int i = 0; i < requirement; ++i) {
cout << "======Fan " << i + 1 << "=======\n";
cout << "Enter name: ";
cin >> fan.name;
cout << "Enter age: ";
cin >> fan.age;
cout << "Enter sex: ";
cin >> fan.sex;
fan.under_auth = false;
fan.auth_level = 0;
fans.push_back(fan);
}
break;
}
default:
cout << "Incorrect choice\n";
break;
}
}
//Soccer Teams member functions
string SoccerTeams::nameTeam(int id) {
return teams.begin() -> teamName;
}
void SoccerTeams::showPlayers() {
cout << "Players in " << teams.begin() -> teamName << endl;
player.showPlayas();
}
void SoccerTeams::showManagers() {
int counter = 1;
list<ManagingDirectors>::iterator i;
for (i = directors.begin(); i != directors.end(); i++) {
cout << "Director " << counter << endl;
cout << "Works for team " << nameTeam(i -> directorId) << endl;
cout << "Name: " << i -> name << endl;
cout << "Sex: " << i -> sex << endl;
counter++;
}
}
void SoccerTeams::addPlayer() {
int newId;
int number;
cout << "Number of players to be added: ";
cin >> number;
for (int i = 0; i < number; ++i) {
cout << "\nEnter player name: ";
cin >> player.name;
cout << "Enter sex(M/F): ";
cin >> player.sex;
cout << "Enter age: ";
cin >> player.age;
cout << "Enter player id(0 for random id): ";
cin >> newId;
newId == 0 ? player.playerId = (rand() % 100 + 1) : player.playerId = newId;
player.under_auth = true;
player.auth_level = 0;
players.push_back(player);
teams.begin()->num_of_people++;
}
}
void SoccerTeams::deletePlayer(int id) {
std::vector<Players>::iterator i;
for (i = players.begin(); i != players.end(); ) {
if(i->playerId == id) {
i = players.erase(i);
teams.begin()->num_of_people--;
}
else
i++;
}
}
void SoccerTeams::showTeam() {
vector<SoccerTeams>::iterator i;
for (i = teams.begin(); i != teams.end(); ++i) {
cout << "\nTeam name: " << i -> teamName << endl;
cout << "Team id: " << i -> teamId << endl;
cout << "Number of players: " << i -> num_of_people << endl;
cout << "Average age: " << i -> player.ageCalc()/teams.begin() -> num_of_people << endl;
}
}
SoccerTeams::SoccerTeams(string tn, int id) {
teamName = tn;
teamId = id;
teams.push_back(*this);
};
void SoccerTeams::addManager() {
ManagingDirectors mandir;
int number;
cout << "How many managers you want to add: ";
cin >> number;
for (int i = 0; i < number; i++) {
cout << "Manager " << i + 1 << endl;
cout << "Enter name of the director: ";
cin >> mandir.name;
cout << "Enter the age: ";
cin >> mandir.age;
cout << "Enter the sex(M/F): ";
cin >> mandir.sex;
mandir.directorId = teams.begin() -> teamId;
mandir.auth_level = 3;
mandir.under_auth = false;
directors.push_front(mandir);
}
}
void SoccerTeams::exportToFile(const char *filename) {
ofstream outfile;
outfile.open(filename, ios::out);
vector<Players>::iterator i;
int counter = 1;
outfile << "Team Data" << endl;
outfile << "Team name : " << teamName << "\nPlayers : " << teams.begin() -> num_of_people << endl;
outfile << "Average age: " << teams.begin() -> player.ageCalc()/teams.begin() -> num_of_people << endl;
for (i = players.begin(); i != players.end(); ++i) {
outfile << "\nPlayer " << counter << endl;
outfile << "Name: " << i -> name << endl;
outfile << "Sex : " << i -> sex << endl;
outfile << "Age : " << i -> age << endl;
outfile << "Pid : " << i -> playerId << endl;
counter++;
}
outfile.close();
}
#ifndef PEOPLE_H
#define PEOPLE_H
//People base class
class people {
string name;
char sex;
int age;
bool under_auth;
int auth_level;
friend class SoccerTeams;
friend class Players;
friend class Fans;
friend class FanClubs;
public:
//virtual string getclass() { return char2str(typeid(*(this)).name()); }
people(){};
~people(){};
//virtual int get_age(){ return this->age; };
};
//players class people
class Players : public people {
int playerId;
int avgAge;
friend class SoccerTeams;
public:
void showPlayas();
float ageCalc();
Players(){};
~Players(){};
};
std::vector<Players> players;
//Class Managing Directors people
class ManagingDirectors : public people {
int directorId;
friend class SoccerTeams;
public:
ManagingDirectors(int);
ManagingDirectors() {};
~ManagingDirectors(){};
};
std::list<ManagingDirectors> directors;
//Fans people class
class Fans : public people {
public:
void showFanas();
Fans(){};
~Fans(){};
};
std::vector<Fans> fans;
#endif
#include <algorithm>
#include <iostream>
#include <vector>
#include <typeinfo>
#include <boost/units/detail/utility.hpp>
#include <cstdlib>
#include <fstream>
#include <list>
#include "people.h"
using namespace std;
const int vector_resizer = 50;
string char2str(const char* str) { return boost::units::detail::demangle(str); }
//Fan class member functions
void Fans::showFanas() {
int counter = 1;
vector<Fans>::iterator i;
for (i = fans.begin(); i != fans.end(); ++i) {
cout << "\nFan " << counter << endl;
cout << "Name: " << i -> name << endl;
cout << "Sex: " << i -> sex << endl;
cout << "Age: " << i -> age << endl;
counter++;
}
}
//Players class member functions
float Players::ageCalc() {
int totalAge = 0;
vector<Players>::iterator i;
for (i = players.begin(); i != players.end(); ++i) {
totalAge += i->age;
}
return totalAge;
}
void Players::showPlayas() {
int counter = 1;
vector<Players>::iterator i;
for (i = players.begin(); i != players.end(); ++i) {
cout << "\nPlayer " << counter << endl;
cout << "Name: " << i -> name << endl;
cout << "Sex: " << i -> sex << endl;
cout << "Age: " << i -> age << endl;
cout << "Player id: " << i -> playerId << endl;
counter++;
}
}
//Member functions of Managing DIrectos
ManagingDirectors::ManagingDirectors(int number) {
directorId = number;
};
除了这些文件,我还有一个makefile。
//makefile
footballmaker: main.o groups.o people.o
gcc -o main main.o groups.o people.o
rm groups.o people.o
同样here's一个文件中的所有代码,它现在的工作方式。
当我尝试制作程序时,我收到以下错误,
gcc -o main main.o groups.o people.o
groups.o:(.bss+0x0): multiple definition of `players'
main.o:(.bss+0x0): first defined here
groups.o:(.bss+0x20): multiple definition of `directors[abi:cxx11]'
main.o:(.bss+0x20): first defined here
groups.o:(.bss+0x40): multiple definition of `fans'
main.o:(.bss+0x40): first defined here
people.o:(.bss+0x0): multiple definition of `players'
main.o:(.bss+0x0): first defined here
people.o:(.bss+0x20): multiple definition of `directors[abi:cxx11]'
main.o:(.bss+0x20): first defined here
people.o:(.bss+0x40): multiple definition of `fans'
main.o:(.bss+0x40): first defined here
...
collect2: error: ld returned 1 exit status
makefile:3: recipe for target 'footballmaker' failed
make: *** [footballmaker] Error 1
整个错误超过400行,附加here。
我不确定如何包含文件,因此我不会复制它们,因为需要文件才能使程序正常工作,是否有更好的方法将我的代码拆分成文件?
答案 0 :(得分:0)
您在头文件people.h
中的文件范围定义(而不仅仅是声明!)变量。在链接时,所有其他翻译单元都可以看到这样的变量定义。如果不同的翻译单元,例如people.cpp
和main.cpp
,现在包含people.h
,这就好像这些变量定义已直接写入people.cpp
和main.cpp
,每次定义一个在全局范围内使用相同名称的单独变量。
为了解决这个问题,声明头文件中的变量,但仅在一个翻译单元中定义,例如people.cpp
。只是声明一个变量意味着将关键字extern
放在它前面(告诉编译器在链接时由不同的翻译单元提供变量定义):
// people.h
extern std::vector<Players> players;
extern std::list<ManagingDirectors> directors;
extern std::vector<Fans> fans;
// people.cpp
std::vector<Players> players;
std::list<ManagingDirectors> directors;
std::vector<Fans> fans;