You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法修改类中变量值,main函数始终获取原始值的问题

问题

我定义了一个包含若干变量的类,在函数里能正常读取这些变量,也看似成功把它们更新成了新值,但回到main()函数里获取的始终是原始值,实在找不到问题所在。

环境:Windows 10 系统,Visual Studio 2022

代码如下:

header.h

#pragma once
#include <string>
#include "gmp.h"

class my_class {
public:
    const static int  CPU_GRP_SIZE = 16;
    mpz_t tempx, tempy;

    my_class()
    {
        mpz_init_set_str(tempx, "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
        mpz_init_set_str(tempy, "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
    }

};

void AddDirect(mpz_t p2x, mpz_t p2y);

main.cpp

#include <string>
#include <iostream>
#include <gmp.h>
#include "header.h"

void main()
{
    my_class secp;
    int hLength = (secp.CPU_GRP_SIZE / 2 - 1);

    mpz_t point2x, point2y;

    mpz_init_set_str(point2x, "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", 16);
    mpz_init_set_str(point2y, "1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a", 16);

    AddDirect(point2x, point2y);

    std::cout << "+++++++++++++ main \n";
    mpz_out_str(stdout, 16, secp.tempx);
    std::cout << " \n";
}

void AddDirect(mpz_t p2x, mpz_t p2y)
{
    my_class secp;

    mpz_t point2x, point2y;

    mpz_init_set(point2x, p2x);
    mpz_init_set(point2y, p2y);
    // ---------------------------

    mpz_set(secp.tempx, point2x);
    mpz_set(secp.tempy, point2y);
    //------------------
    std::cout << "adddirect secp.tempx\n";
    mpz_out_str(stdout, 16, secp.tempx);
    std::cout << " \n";
}

预期输出:

adddirect secp.tempx 
c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5
 +++++++++++++ main 
c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5

实际输出:

adddirect secp.tempx
c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5 
+++++++++++++ main 
79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
解决方案

问题核心在于:AddDirect函数内部新建了一个独立的my_class对象,和main()里的secp完全是两个不同的实例。你在AddDirect里修改的是这个局部对象的tempx/tempy,修改完成后这个局部对象就被销毁了,main()里的原对象根本没被改动。

有两种常见修复方式:

方法1:将对象通过引用传入函数

修改AddDirect的参数,让它接收my_class的引用,这样函数里操作的就是main()里的原对象:

修改后的header.h

#pragma once
#include <string>
#include "gmp.h"

class my_class {
public:
    const static int  CPU_GRP_SIZE = 16;
    mpz_t tempx, tempy;

    my_class()
    {
        mpz_init_set_str(tempx, "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
        mpz_init_set_str(tempy, "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
    }

};

// 修改函数参数,添加my_class引用
void AddDirect(my_class& secp, mpz_t p2x, mpz_t p2y);

修改后的main.cpp

#include <string>
#include <iostream>
#include <gmp.h>
#include "header.h"

int main() // 标准C++要求main返回类型为int
{
    my_class secp;
    int hLength = (secp.CPU_GRP_SIZE / 2 - 1);

    mpz_t point2x, point2y;

    mpz_init_set_str(point2x, "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", 16);
    mpz_init_set_str(point2y, "1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a", 16);

    // 传入secp对象的引用
    AddDirect(secp, point2x, point2y);

    std::cout << "+++++++++++++ main \n";
    mpz_out_str(stdout, 16, secp.tempx);
    std::cout << " \n";

    // 释放mpz资源,避免内存泄漏
    mpz_clear(point2x);
    mpz_clear(point2y);
    return 0;
}

void AddDirect(my_class& secp, mpz_t p2x, mpz_t p2y)
{
    // 不需要再新建my_class对象,直接用传入的引用
    mpz_t point2x, point2y;

    mpz_init_set(point2x, p2x);
    mpz_init_set(point2y, p2y);

    mpz_set(secp.tempx, point2x);
    mpz_set(secp.tempy, point2y);

    std::cout << "adddirect secp.tempx\n";
    mpz_out_str(stdout, 16, secp.tempx);
    std::cout << " \n";

    // 释放局部mpz资源
    mpz_clear(point2x);
    mpz_clear(point2y);
}

方法2:将AddDirect改为类的成员函数

既然AddDirect是操作my_class对象的方法,直接把它定义成类的成员函数更符合面向对象设计:

修改后的header.h

#pragma once
#include <string>
#include "gmp.h"

class my_class {
public:
    const static int  CPU_GRP_SIZE = 16;
    mpz_t tempx, tempy;

    my_class()
    {
        mpz_init_set_str(tempx, "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
        mpz_init_set_str(tempy, "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
    }

    // 定义成员函数
    void AddDirect(mpz_t p2x, mpz_t p2y);
};

修改后的main.cpp

#include <string>
#include <iostream>
#include <gmp.h>
#include "header.h"

int main()
{
    my_class secp;
    int hLength = (secp.CPU_GRP_SIZE / 2 - 1);

    mpz_t point2x, point2y;

    mpz_init_set_str(point2x, "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", 16);
    mpz_init_set_str(point2y, "1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a", 16);

    // 调用成员函数
    secp.AddDirect(point2x, point2y);

    std::cout << "+++++++++++++ main \n";
    mpz_out_str(stdout, 16, secp.tempx);
    std::cout << " \n";

    mpz_clear(point2x);
    mpz_clear(point2y);
    return 0;
}

// 实现成员函数
void my_class::AddDirect(mpz_t p2x, mpz_t p2y)
{
    mpz_t point2x, point2y;

    mpz_init_set(point2x, p2x);
    mpz_init_set(point2y, p2y);

    // 直接操作当前对象的tempx/tempy
    mpz_set(tempx, point2x);
    mpz_set(tempy, point2y);

    std::cout << "adddirect secp.tempx\n";
    mpz_out_str(stdout, 16, tempx);
    std::cout << " \n";

    mpz_clear(point2x);
    mpz_clear(point2y);
}

另外补充两个细节:

  1. 标准C++中main函数的返回类型必须是int,不能是void,修改后更规范。
  2. 使用mpz_t后记得调用mpz_clear释放资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Josh Wert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:24:52