为什么这些函数使用vector的不同副本?

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

本文关键字:副本 vector 函数 为什么      更新时间:2023-10-16

我有一个问题,类函数在一个向量的不同副本上进行更改,而不是在相应对象的实例中保存一个。

Main函数描述:这是主要功能。它首先创建类Mats的对象Menno,用它的构造函数初始化,并有一个类型为int的私有向量F,其中充满了值-1。然后使用它来创建一个名为CalliCalculator类对象。对象Menno保存在Calli中名为MatricesMats类型的私有对象变量中。最后,MatricesCalligetMatrices()函数返回,printF()在这个对象变量上执行,它改变了F中的值,并且应该永远改变F

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

背景:

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

// 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();

返回类成员的副本。将其更改为通过引用返回:

 Mats &getMatrices();

注意,通过引用返回类成员有一些需要理解的后果。你可以在你最喜欢的c++书中找到所有的细节。

这里发生的事情是你自我描述的Java背景阻碍了你。c++类的工作方式与Java的类有本质上的不同。您需要忘记您所知道的关于类的一切知识,就像您在Java中所知道的那样,并从基础开始专注于学习c++类是如何工作的。