C ++函数返回没有某些字段的对象

时间:2014-05-13 01:45:18

标签: c++ function pointers reference

我有一个项目,可以创建一个计划并对其进行优化。该项目具有Schedule类:

Schedule.h:

#pragma once
#ifndef SCHEDULE_H
#define SCHEDULE_H

#include "Course.h"
#include "Prof.h"
#include "Room.h"
#include "TimeBlock.h"
#include "Weekdays.h"
#include "ScoreCalculator.h"
#include <map>
#include <vector>
/**
 * This class represents a schedule for all courses.
 */
class Schedule {
public:
    Schedule(std::vector < Room >, std::vector < Prof >, std::vector < Course > );
    Schedule(const Schedule& schedule);
    std::map < Room, std::vector < std::vector < Course > > > getSchedule();
    bool setCourse(const Course&, const Room&, Weekdays, TimeBlock, int);
    Course getCourse(const Room&, Weekdays, TimeBlock);
    std::vector < Course > getCoursesAt(Weekdays, TimeBlock);
    std::vector < Weekdays > getWeekdaysFor(const Course&);
    TimeBlock getTimeFor(const Course&);
    Room getRoomFor(const Course&);
    void swapCourses(Room, Weekdays, TimeBlock, Room, Weekdays, TimeBlock);
    void setScore (double score){ _score = score; }
    double getScore() { return _score; }
    Prof getProf(string);
    Prof getProf(Course);
    std::vector<Course> getCoursesTaughtBy(Prof&);
    std::vector<Course> getCoursesOnGivenDayTaughtBy(Prof&, Weekdays);
    std::vector<Room> getRooms();
    std::map<string, Prof> getProfs();
    void setSchedule(std::map < Room, std::vector < std::vector <Course> > >);
private:
    std::map < Room, std::vector < std::vector < Course > > > _schedule;
    std::map < std::string, Prof > _professors;
    std::map < std::string, Course > _courses;
    std::vector<Room> _rooms;
    std::vector<Prof> _profs;
    std::vector<Course> _coursesVector;
    double _score;
};

#endif // SCHEDULE_H

Schedule.cpp:

#include "../include/Schedule.h"
#include "../include/Prof.h"
#include <vector>
#include <set>
#include <string>

using namespace std;

/**
 * Constructor for the schedule. Creates the empty schedule
 */
Schedule::Schedule(vector < Room > rooms, vector < Prof > prof, vector < Course > courses){
    _rooms = rooms;
    _profs = prof;
    _coursesVector = courses;
    for(unsigned int i = 0; i < prof.size(); i++){
            _professors.insert(make_pair(prof.at(i).getId(), prof.at(i)));
    }
    for (unsigned int i = 0; i < courses.size(); i++){
        _courses.insert(make_pair(courses.at(i).getId(), courses.at(i)));
    }
    _score = -1;
    for (unsigned int i = 0; i < _rooms.size(); i++){
        vector < vector < Course > > dayVector;
        dayVector.resize(WEEKDAYS_SIZE);
        for (unsigned int j = 0; j < dayVector.size(); j++){
            dayVector.at(j).resize(TIMEBLOCK_SIZE);
        }
        _schedule.insert(make_pair(_rooms.at(i), dayVector));
    }
}

bool Schedule::setCourse(const Course& course, const Room& room, Weekdays firstMeeting, TimeBlock timeBlock, int numberOfMeetings){
    if (course.getEnrolled() > room.getCapacity()){
        return false;
    }
    _schedule.at(room).at(firstMeeting).at(timeBlock) = course;

    switch (numberOfMeetings){
    case 2:
        _schedule.at(room).at((TimeBlock)(firstMeeting + 2)).at(timeBlock) = course;
        break;
    }
    return true;
}

Course Schedule::getCourse(const Room& room, Weekdays day, TimeBlock timeBlock){
    //returns course
}

vector < Course > Schedule::getCoursesAt(Weekdays day, TimeBlock timeBlock){
    //returns course at the given time
}

TimeBlock Schedule::getTimeFor(const Course& course){
    //returns time for the course
}

Room Schedule::getRoomFor(const Course& course){
    //returns room for the course
}

vector < Weekdays > Schedule::getWeekdaysFor(const Course& course){
    //returns weekdays for the course
}

// returns true if swap was successful, false otherwise
void Schedule::swapCourses(Room room1, Weekdays weekdays1, TimeBlock timeBlock1, Room room2, Weekdays weekdays2, TimeBlock timeBlock2){
    Course c1, c2;
    c1 = getCourse(room1, weekdays1, timeBlock1);
    c2 = getCourse(room2, weekdays2, timeBlock2);
    setCourse(c2, room1, weekdays1, timeBlock1, 2);
    setCourse(c1, room2, weekdays2, timeBlock2, 2);
}

Prof Schedule::getProf(string id){
    return _professors.at(id);
}

Prof Schedule::getProf(Course c){
    return _professors.at(c.getProfId());
}


void Schedule::setSchedule(map < Room, vector < vector < Course > > > schedule){
    _schedule = schedule;
}

map < Room, vector < vector < Course > > > Schedule::getSchedule(){
    return _schedule;
}

vector<Room> Schedule::getRooms(){
    return _rooms;
}

map <string, Prof> Schedule::getProfs(){
    return _professors;
}

vector <Course> Schedule::getCoursesTaughtBy(Prof& prof){
    //returns courses taught by
}

Schedule& Schedule::operator=(const Schedule& rhs){
    _rooms = rhs._rooms;
    _courses = rhs._courses;
    _coursesVector = rhs._coursesVector;
    _professors = rhs._professors;
    _profs = rhs._profs;
    _schedule = rhs._schedule;
    return *this;
}

它有一个类,通过交换两个随机课程并决定处理优化,哪个时间表更好:

GeneticScheduleGenerator.h:

#pragma once
#ifndef GENETICSCHEDULEGENERATOR_H
#define GENETICSCHEDULEGENERATOR_H

#include "ScheduleGenerator.h"
#include "ScoreCalculator.h"
#include "Schedule.h"
#include <map>
#include <string>
using namespace std;

class GeneticScheduleGenerator : public ScheduleGenerator {
public:
  GeneticScheduleGenerator(ScoreCalculator&, Schedule*, long);
  Schedule* getSchedule(void);
  Schedule* _schedule;
  map < Room, vector < vector < Course > > > getScheduleMap();
private:
    double calculateScore(map < string, Prof >, Schedule*);
  void optimize ();
  std::map<string, ProfInfo> profInfoMap;
  ScoreCalculator& _sc;
  map<string, double> _scores;
  map<Room, vector< vector< Course> > > _scheduleMap;


};

#endif // GENETICSCHEDULEGENERATOR_H

GeneticScheduleGenerator.cpp:

#include "../include/GeneticScheduleGenerator.h"
#include <cstdlib>
#include <time.h>
#include <algorithm>
#include "../include/Weekdays.h"
#include "../include/TimeBlock.h"
#include <iostream>

GeneticScheduleGenerator::GeneticScheduleGenerator(ScoreCalculator& sc, Schedule* schedule, long timeout )
    : ScheduleGenerator(timeout) , _sc(sc) {
        _schedule = schedule;
}

double GeneticScheduleGenerator::calculateScore(map<string, Prof> professors, Schedule* schedule){
    double score = 0;
    //does some calculations
    return score;
}

Schedule* GeneticScheduleGenerator::getSchedule(){
    Schedule* bestSchedule = _schedule;
    Schedule _changedSc = *_schedule;
    Schedule *_changedSchedule = &_changedSc;
    map<string, Prof> professors = bestSchedule->getProfs();

    bestSchedule->setScore(calculateScore(professors, bestSchedule));

    srand(time(NULL));
    vector<Room> rooms = _schedule->getRooms();
    int numberOfRooms = rooms.size();
    Room room1, room2;
    Weekdays day1, day2;
    TimeBlock time1, time2;

    long endTime = time(0) + getTimeout();
    int counter = 0;
    do{
        counter++;
        room1 = rooms.at(rand() % numberOfRooms);
        room2 = rooms.at(rand() % numberOfRooms);
        day1 = (Weekdays)(rand() % WED);
        day2 = (Weekdays)(rand() % WED);
        time1 = (TimeBlock)(rand() % TIMEBLOCK_SIZE);
        time2 = (TimeBlock)(rand() % TIMEBLOCK_SIZE);
        if (_changedSchedule->getCourse(room1, day1, time1).getEnrolled() > room2.getCapacity() ||
            _changedSchedule->getCourse(room2, day2, time2).getEnrolled() > room1.getCapacity() ||
            _changedSchedule->getCourse(room2, day2, time2) == _changedSchedule->getCourse(room1, day1, time1))
        {
            continue;
        }
        else
        {
            bestSchedule = _schedule;


            _changedSchedule->swapCourses(room1, day1, time1, room2, day2, time2);
            double newScore = calculateScore(professors, _changedSchedule);

            if (bestSchedule->getScore() > newScore){
                _schedule = _changedSchedule;
                _schedule->setScore(newScore);
            }
        }

    } while (time(0) < endTime);
    std::cout << "counter: " << counter << endl;
    _scheduleMap = _schedule->getSchedule();
    /*map<string, Prof> tempProf = _schedule->getProfs();
    map<string, Course> tempCorse = _schedule->getCourses();*/

    return _schedule;
}

map < Room, vector < vector < Course > > > GeneticScheduleGenerator::getScheduleMap(){
    return _scheduleMap;
}

ScheduleGeneratorClass尚未完全运作(它不会测试类冲突,即同一教授不能同时教授2个班级),但它会交换课程并计算日程安排的分数。问题是,在返回_schedule之前; part _schedule包含有效的时间表:

enter image description here

但是当调用者得到它时,该对象只保留得分部分。其他一切似乎都被抹去了:

enter image description here

过去几天我一直试图解决这个问题而且没有运气。 有人可以帮忙吗? 如果您需要其他代码或更多信息,请询问。 谢谢。

2 个答案:

答案 0 :(得分:3)

getSchedule这些代码行中:

Schedule _changedSc = *_schedule;
Schedule *_changedSchedule = &_changedSc;

在堆栈上创建{strong>本地实例Schedule,并指向该本地实例。

这行代码:

_schedule = _changedSchedule;

表示_schedule现在指向该局部变量。

当您的方法返回时,局部变量超出范围,因此您的_schedule指针现在无效。

向量大小变回零的原因可能是由于向量析构函数,但是没有什么能阻止程序将该内存重用于其他内容,如果您尝试使用向量,则会出现段错误。

解决此问题的一种方法是拥有一个更长久的地方来存储已更改的Schedule,例如在课堂上。另一种方法是传入一个Schedule对象来填充。另一种方法是将Schedule作为对象而不是指针传回。

答案 1 :(得分:0)

使用new运算符,您知道该对象不会在初始化范围内使用。例如:

Schedule *_changedSchedule = &_changedSc;

_changedSc超出范围时,它将不再在堆栈中。您需要能够使用new运算符将其存储在堆中。