函数调用后,初始化变量会丢失值

时间:2010-05-27 21:33:23

标签: c++ function class

问题说明了一切,真的。我不确定问题是什么。我对班级很新;我与他们的实践经验接近于nill,但我已经阅读了相当多的关于他们的内容。

我使用以下构造函数

创建了一个类ECard
ECard::ECard( int bankNum, int PIN )
{
    m_BankNum     = new int;
    m_PIN         = new int;
    m_Barred      = new bool;
    m_Amount      = new double;

    *m_BankNum     = bankNum;
    *m_PIN         = PIN;
    *m_Barred      = false;
    *m_Amount      = 100.0;
}

我用EC card( 12345, 54321 )

初始化

我还有一个成员函数display(),它只打印出所有成员变量BankNum,PIN,Barred和Amount。

当我在main函数中调用此函数card.display()时,输出完全符合我的预期。

然而,当它进入我的循环时:

/* Fine values! */
card.display();
while( true )
{
    /* Introductory screen giving user options to choose from */
    mainScreen( card );
    /* Make a choice... */
    choice = readInput();
    /* Garbage! */
    card.display();
    /* Pass it to the switch, watch out for invalid input! doChoice is a bool */
    if( !doChoice( choice, card ) )
    {
        cout << "Bad input- repeat!" << endl;
    }
    /* TODO: Option to terminate loop. */
}

我尝试在doChoice()函数中打印变量,我得到了垃圾。我的所有变量都搞砸了设置。我的Banknumber是一个东西,PIN是一个非常大的负数(不是MIN),Barred突然设置为true,并且我的帐户中有0个钱,即使Barred和Amount在构造函数之外的任何地方都没有明确设置。< / p>

/* Outsourced switch that handles the user input from MAIN */
bool doChoice( int choice, ECard card )
{
    int inputPIN;
    int inputAmount;

    /* Garbage! */
    card.display();

    switch( choice )
    {
    case 1:
    /* Case 1: Charge card with money. Needs PIN and amount */
        cout << "PIN Eingeben:  ";
        inputPIN    = readInput();
        cout << "\nBetrag Eingeben:  ";
        inputAmount = readInput();

        karte.aufladen( inputAmount, inputPIN );

        return true;

如果某些成员函数和输出仍然是德语,我很抱歉。无论如何它都不应该是重要的(因为我可能会为国际公司编程,但我喜欢用英语编写所有作业,但如果我的编程超出他的预期,我的老师非常挑剔并降低我的成绩)

变量在进入开关之前已经搞砸了,所以这部分应该只是修辞。我只能看到卡片对象的传递问题,但我不知道为什么会出现问题。我不知道如何修复它,我只是发送每个成员吗?创建一个指向该对象的指针并发送它?我的意思是,我之前传递了卡片对象,而其他功能并没有给我垃圾。只有这一个。

最后一点,如果语法中突然出现错误,那是因为我很快将我的所有功能和成员翻译成英语,我可能错过了某个地方的大写或什么。请忽略这些,语法正确并且程序运行,它只显示垃圾值。

3 个答案:

答案 0 :(得分:6)

您正在按值传递卡片。但是因为你有很多指针,并且可能没有编写复制构造函数,所以卡的副本使用指针来改变主循环中“旧”卡也在使用的内存。然后当函数退出时,可能你有一个卡析构函数删除所有成员变量?所以你基本上有悬空指针。如果没有ECard的所有代码,我无法确定,但这是我的猜测。

我不会在卡片上有指针。我认为int *在那里没有任何好处。然后,因为你想要doChoice更换卡片,所以需要一个ECard&amp;所以它可以改变你在主要使用的真实。

答案 1 :(得分:3)

mainScreen()是否将'card'作为引用或值传递?发生的是调用创建一个新的本地副本并调用默认构造函数,该构造函数不分配内存或初始化局部变量。 doChoice()也发生了同样的事情。在这两个函数中通过引用传递,它应该解决这个问题。

即。 - bool doChoice(int choice,ECard&amp; card)

答案 2 :(得分:1)

除非必要,否则不要动态分配变量

在Java语言中,使用new运算符定义变量实例。这在C ++中不是必需的。

将您的班级声明更改为:

struct ECard
{
    ECard(unsigned int bankNum,
          unsigned int newPIN)
    : m_bankNum(bankNum),
      m_pin(newPIN),
      m_barred(false),
      m_amount(100.0)
  {
    ;
  }

  unsigned int m_bankNum; // Can bank numbers be negative???
  unsigned int m_pin;
  bool         m_barred;
  double       m_amount;
};

指针

如果您确实需要为成员动态分配内存,请使用智能指针。智能指针将在需要时自动释放内存。我建议使用Boost库。

如果你不能使用智能指针,记得在析构函数中释放内存:

ECard::
~ECard()
{
  delete m_p_bankNum;
  delete m_p_pin;
  delete m_p_barred;
  delete m_p_amount;
}

如果你不在类或结构中使用指针,你可以避免动态内存分配和释放的麻烦,特别是对于复制和销毁(谁拥有内存?)。