C++:为什么这些函数使用向量的不同副本?

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

我遇到的问题是 class 函数对向量的不同副本进行更改,而不是对保存在相应对象实例中的副本进行更改。

主要功能说明: 这是主要功能。它首先创建一个 class Mats 的对象 Menno,该对象使用其构造函数进行初始化,并具有一个名为 F 的类型为 int 的私有向量 F -1。然后它用于创建一个名为 Calli class Calculator 的对象。对象 Menno 保存在 Calli 中名为 Matrices 的类型 Mats 的私有对象变量中。最后,MatricesCalligetMatrices() 函数返回,并且 printF() 在此对象变量上执行,它更改 F 中的值并且应该一直更改 F

问题: 执行程序后可以看出,printF()setf() 所做的更改不会保存在对象变量 Matrices 中。这使我认为 F 在构造函数中的初始化工作正常,但函数随后使用此向量的其他副本而不是保存的副本。

背景: 作为一名 Java 编码员,我被建议在大多数情况下使用指针,但我仍然不明白为什么这段代码不能按预期工作。我最近研究了 C++ 作为一种编程语言,浏览了 newbostons 视频指南并打印了语法列表,但它们在这里对我没有帮助。任何解释表示赞赏!

// 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;
}

因为

 Mats getMatrices();

returns class 成员的副本。通过引用将其更改为 return:

 Mats &getMatrices();

请注意,通过引用 returning 一个 class 成员会产生某些您需要了解的后果。您将在您最喜欢的 C++ 书籍中找到所有详细信息。

这里发生的事情是你在 Java 中自我描述的背景妨碍了你。 C++ classes 的工作原理与 Java 的 classes 根本不同。你需要忘记你所知道的关于 classes 的一切,正如你在 Java 中所知道的那样,并专注于从基础开始学习 C++ classes 是如何工作的。