1

I have a class Project and each Project can have different tasks.

Project.h:

#pragma once
#include "Task.h"
#include <vector>

using namespace std;

class Project
{
  private:
    vector<Task> Tasks;
  public:

    Project::Project(int inleesgetal);//constructor

    vector<Task> GetTasks();
};

Project.cpp:

#include "Project.h"
#include <string>
#include <vector>
Project::Project(int inleesgetal)
{

    //constructor
    Tasks.resize(Numbertasks);
}

vector<Task> Project::GetTasks()
{
    return Tasks;
}

Task.h:

#pragma once
#include <vector>

using namespace std;

class Task
{

  private:
    //Info:

    int StartTime_Solo;

  public:

    Task(); //constructor

    void SetStartTime_Solo(int st_s);

    int GetStartTime_Solo();

};

Task.cpp:

#include "Task.h"
#include <string> 
#include <vector>
#include <iostream>

using namespace std;


Task::Task()
{
    //constructor
    StartTime_Solo = 0;
}

int Task::GetStartTime_Solo()
{
    return StartTime_Solo;
}

void Task::SetStartTime_Solo(int st_s)
{
    StartTime_Solo = st_s;
}

main:

#include <iostream>
#include <vector>

#include "Task.h" 
#include "Project.h"

using namespace std;


int main()
{

    Project Project1(6);

    Project1.GetTasks()[2].SetStartTime_Solo(55);
    cout << "test:" << Project1.GetTasks()[2].GetStartTime_Solo();
    return 0;
}

Now when I try to set the 3rd task of Project1 to a starttime of 55 and then print the start time out it still gives me 0 as a result. Why is this? And how can I change my code so it actually sets the starttime to 55?

sokkyoku
  • 2,161
  • 1
  • 20
  • 22
Pieter
  • 13
  • 4
  • 1
    Setters and getters in the form `setX` and `getX` are _Java-ish_ indeed. – skypjack Oct 13 '16 at 16:09
  • 1
    `vector GetTasks();` returns a copy of your member `vector Tasks;` So `Project1.GetTasks()[2].SetStartTime_Solo(55);` will only update the copy. BTW: You should write variables and members in lower case - it will be much easier to distinguish between variables/members and classes. – Simon Kraemer Oct 13 '16 at 16:11
  • [Avoid `using namespace std;`](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) -- especially in headers. – Dan Mašek Oct 13 '16 at 16:45

2 Answers2

2
vector<Task> GetTasks();

should be

const vector<Task>& GetTasks() const;
vector<Task>& GetTasks();

And so with definitions:

vector<Task> Project::GetTasks()
{
    return Tasks;
}

should be:

const vector<Task>& Project::GetTasks() const { return Tasks; }
vector<Task>& Project::GetTasks() { return Tasks; }
Jarod42
  • 203,559
  • 14
  • 181
  • 302
2

The problem is that you are returning a copy of the vector<Task> from the GetTasks function. You then modify this copy and throw it away right afterwards. The internal member of Project is not changed.

If you return by reference like this:

vector<Task>& GetTasks();

Then you are basically returning something that points to the internal vector, and so when you modify it, you actually modify the member data of your class.

sji
  • 1,877
  • 1
  • 13
  • 28
  • You missed the const version (and the volatile one) but this explained the why well. – UKMonkey Oct 13 '16 at 16:20
  • Thanks! So I tried to work with this but I still have a question. I added this to the constructor in Project.cpp: Projectduration = 0; And 2 methods: int Project::GetProjectDuration() { return Projectduration; } void Project::SetProjectDuration(int prdur) { Projectduration = prdur; } – Pieter Oct 13 '16 at 17:54
  • and in the main: Project1.SetProjectDuration(10); cout << "Projectduration : " << Project1.GetProjectDuration(); And this seems to work? Why do we not need pointers here? – Pieter Oct 13 '16 at 17:56
  • @Pieter Thats a big topic, but it's all about the copying of data when it comes to pointers. Passing a pointer to an object means you don't have to copy it, so if for example it was an array that took 2GB of memory you could avoid copying it and having a bad day. I suggest you read this SO answer: http://stackoverflow.com/a/163544/1230538 – sji Oct 14 '16 at 08:51