Search code examples
c++variablespointersobjectinstances

C++: Why do these functions use different copies of the vector?


I have the problem of class functions making changes on different copies of a vector rather than the one saved in an instance of the corresponding object.

Description of the Main function: This is the main function. It first creates an object Menno of class Mats, which is initialized with its constructor and has a private vector of type int named F full of values -1. It then is used to create an object of class Calculator named Calli. The object Menno is saved in a private object variable of type Mats named Matrices in Calli. Finally, Matrices is returned by the getMatrices() function of Calli and printF() is carried out on this object variable, which changes values in F and is supposed to change F for all time.

Problem: As can be seen after executing the program, the changes made by printF() and setf() do not get saved in the object variable Matrices. This leads me to think that the initialization of F in the constructor works well, but the functions then use other copies of this vector rather than the saved one.

Background: As a Java Coder, I was advised to use pointers for most cases, but I still can't understand why this code doesn't work as intended. I recently investigated C++ as a programming language, went through thenewbostons video guide and printed out syntax lists but they don't help me here. Any explanation is appreciated!

// main function
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int N = 4;
    Mats Menno(N);
    Calculator Calli(Menno);
    Calli.getMatrices().printF();
    Calli.getMatrices().setf(2,1);
    Calli.getMatrices().printF();
}

// Calculator header
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include "Mats.h"
#include <vector>

class Calculator
{
    public:
        Calculator(Mats M);
        Mats getMatrices();
    protected:

    private:
        Mats Matrices;
};

#endif // CALCULATOR_H

// Calculator cpp
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;

Calculator::Calculator(Mats M)
: Matrices(M)
{
}

Mats Calculator::getMatrices(){
    return Matrices;
}

// Mats header
#ifndef MATS_H
#define MATS_H
#include "Calculator.h"
#include <vector>

class Mats
{
    public:
        Mats(int N);
        int getf(int i);
        void setf(int i, int fh);
        std::vector<int> getF();
        void printF();
    protected:

    private:
        std::vector<int> F;
};

#endif // MATS_H

// Mats cpp
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;

Mats::Mats(int N)
{
    std::vector<int> Fh;
    F = Fh;
    F.resize(N);
    for (int i = 0;i<N;i++){
        F[i] = -1;
    }
}

int Mats::getf(int i){
    return F[i];
}

void Mats::setf(int i, int fh){
    F[i] = fh;
}

std::vector<int> Mats::getF(){
    return F;
}

void Mats::printF(){
    F[1] = 300;
    cout << "F: " << endl;
    for (int i = 0; i<F.size(); i++) {
        cout << F[i] << " ";
    }
    cout << endl;
    F[1] = 200;
}

Solution

  • Because

     Mats getMatrices();
    

    returns a copy of the class member. Change it to return it by reference:

     Mats &getMatrices();
    

    Note that returning a class member by reference has certain ramifications that you need to understand. You will find all the details in your favorite C++ book.

    What happened here is that your self-described background in Java is getting in the way. C++ classes work fundamentally different than Java's classes. You need to forget everything you know about classes, as you know them in Java, and focus on learning how C++ classes work, from the basics.