C++ C++;从main()通过类函数传递指针

C++ C++;从main()通过类函数传递指针,c++,class,pointers,C++,Class,Pointers,我知道指针是经常被讨论的东西。为了解决这个问题,我做了很多研究,但一切都让我走到了死胡同 我有一个作业要求我创建一个记录单个测试分数的类。如果已记录测试分数,且新分数更高,则覆盖该分数。如果已记录,且新分数较低,则不执行任何操作。如果没有录制,请录制 以下是我到目前为止的情况: // CIS 235 exercise 7 #include <iostream> using namespace::std; // declare a class for recording

我知道指针是经常被讨论的东西。为了解决这个问题,我做了很多研究,但一切都让我走到了死胡同

我有一个作业要求我创建一个记录单个测试分数的类。如果已记录测试分数,且新分数更高,则覆盖该分数。如果已记录,且新分数较低,则不执行任何操作。如果没有录制,请录制

以下是我到目前为止的情况:

//  CIS 235 exercise 7

#include <iostream>


using namespace::std;

//   declare a class for recording a test score
//   the data will be pointer to an integer, rather than an integer
//
//   - this exercise is designed to show how to work with pointer memory
//   - of course, we would NOT normally use a pointer for just an integer
//   - to illustrate the concepts, but keep the implementation simple,
//             integer data was used.  The general case would be object data,
//             not integer data

class testScore
{
   public:
   //  declare a default constructor - the pointer should be set to NULL
   testScore();
   //  declare a function that returns a bool, indicating if the test has been taken
   bool hasTestTaken();
   //  declare a function to record the test score, the parameter will be an integer
   //  use the following rules
   //  -  if no test has been taken, allocate memory and record the score
   //  -  if a test has been taken and the parameter is less than or equal to
   //         the score, do nothing
   //  -  if the test has been taken and the parameter is  higher than the score,
   //         - release the old memory
   //         - allocate new memory
   //         - record the score
   void recordScore(int *myScore);
   //   declare a function to print the score to an ostream parameter
   //   if the test has not been taken, send an appropriate message to the ostream
   //         otherwise print the score
   void printScore(ostream &out);
   //   declare the destructor
   //   be CAREFUL, you will need an if statement in your destructor
   ~testScore();

   private:
   //  declare the data needed to implement the class
   bool testTaken;
   int *score;
 };

//  write the 5 member functions

testScore::testScore() : score(NULL)
{
//  declare a default constructor - the pointer should be set to NULL
}

bool testScore::hasTestTaken()
{
   //  declare a function that returns a bool, indicating if the test has been taken
   return testTaken;
}

void testScore::recordScore(int *myScore)
{
   if(testTaken == false)
   {
                testTaken = true;
                *score = *myScore;
   }
   else if(testTaken == true && *myScore > *score)
   {
                score = NULL;
                delete score;
                score = new int;
                *score = *myScore;
   }

}

void testScore::printScore(ostream& out)
{
      //   declare a function to print the score to an ostream parameter
   //   if the test has not been taken, send an appropriate message to the ostream
   //         otherwise print the score
     if(testTaken)
     {
                  out << *score << endl;
     }
     else
         out << "The test has not been taken!" << endl;
}

testScore::~testScore()
{
   //   declare the destructor
   //   be CAREFUL, you will need an if statement in your destructor
   if(score != NULL)
   {
             score = NULL;
             delete score;
   }
   else
       delete score;

}

//  test the class member functions
//    - declare an object, but do NOT record a score for the object

//    - declare a second object and record the scores of 83, 78, 92
//       use appropriate member print functions to verify your code
//int abc = 83;
int abc = 0;
int main()
{
//    int abc = 0;
//    int * score2;
//    myTestScore = new int;
//    *myTestScore = 83;

    testScore firstScore;
    firstScore.printScore(cout);

    testScore secondScore;
//    secondScore.recordScore(&abc);
      secondScore.recordScore(&abc);
//    secondScore.printScore(cout);
//    *myTestScore = 78;
//    secondScore.recordScore(myTestScore);
//    secondScore.printScore(cout);
//    *myTestScore = 92;
//    secondScore.recordScore(myTestScore);
//    secondScore.printScore(cout);


   system("PAUSE");
   return 0;
}
我不知道为什么T.T

我也尝试过:

宣布

int *myTestScore;
myTestScore = new int;
*myTestScore = 83;
在main()内部,但在其他内容之前,通过以下方式将myTestScore传递给recordScore:

&myTestScore
编译错误:调用“testScore::recordScore(int**)”时没有匹配的函数; 在secondScore.recordScore行

*myTestScore
myTestScore
编译错误:从“int”到“int*”的转换无效 在secondScore.recordScore行

*myTestScore
myTestScore
没有编译错误,在将任何内容输出到控制台之前运行时崩溃

我试着声明:

int *myTestScore = 83; 
在int main()的内部 编译错误:从“int”到“int*”的转换无效 在int*myTestScore=83行上

我还尝试了各种方法,将recordScore更改为使用&'s和*,以及两者都不使用,以及两者的不同组合

我现在没有想法去尝试,即使在研究之后,我也不能想出任何东西。我试着问我的教授(一个星期了,在线课程),打电话给她,发电子邮件给她,但她没有回答我的任何问题,甚至没有要求开会

我觉得这里有一些简单的东西我没有掌握,我真的很感谢任何人能给我帮助来解决这个问题

非常感谢您抽出时间


变化:

testScore::testScore() : score(NULL), testTaken(false) // didnt change because instructor instructions, but did move testTaken up cause that is where it should be
{
    //  declare a default constructor - the pointer should be set to NULL
}

void testScore::recordScore(int myScore)
{
   if(testTaken == false)
   {
                testTaken = true;
                score = &myScore;
                cout << *score << endl; //this prints correctly, 0
   }
   else if(testTaken == true && myScore > *score)
   {
                //removed the score = NULL to avoid a memory leak (I think this is correct now?)
                delete score;
                score = new int;
                score = &myScore;
   }

}

void testScore::printScore(ostream& out)//no changes, just easier to access to you dont have to keep scrolling up
{
      //   declare a function to print the score to an ostream parameter
   //   if the test has not been taken, send an appropriate message to the ostream
   //         otherwise print the score
     if(testTaken)
     {
                  out << *score << endl; //outputs incorrect 4469696
     }
     else
         out << "The test has not been taken!" << endl;
}

int main()
{
    int abc = 0;

    testScore firstScore;
    firstScore.printScore(cout);

    testScore secondScore;
    secondScore.recordScore(abc);
    secondScore.printScore(cout);

   system("PAUSE");
   return 0;
}
testScore::testScore():score(NULL),testtake(false)//没有因为讲师的指示而更改,但确实移动了testtake,因为它应该在那里
{
//声明默认构造函数-指针应设置为NULL
}
void testScore::recordScore(intmyscore)
{
if(testtake==false)
{
testtake=true;
分数=&myScore;

cout主要问题是,在默认构造函数中,您将
NULL
赋值给score,因此指针将指向无效内存。因此,当您调用recordStore时,当程序到达此指令时:

 *score = *myScore;
它会导致分段错误,当您试图覆盖程序未使用的内存部分时会发生此错误

程序不会在printScore中崩溃,因为读取无效指针不是错误,但会读取垃圾数据

编辑:根据您的分配,如果未进行测试,则必须在recordStore中分配指针,因此在recordStore中,更改此部分:

if(testTaken == false)
{
                testTaken = true;
                *score = *myScore;
}
为此:

if(testTaken == false)
{
                score = new int;
                testTaken = true;
                *score = *myScore;
}

另外,在执行
delete
部分时,首先将指针指定为NULL,然后将其删除;因此程序将尝试删除
NULL
指针(这不会导致错误),并且用于
分数的内存未释放,导致内存泄漏

声明一个函数来记录测试分数,参数将是一个整数。您声明它将指针指向一个整数。阅读您的问题,我建议您停下来,深呼吸,然后重新阅读指针上的材料。如果您在t*myScore=83;
需要问一下,这意味着你需要学习更多。Merr,一开始她说://声明一个用于记录考试分数的类//数据将指向一个整数,而不是一个整数,这是类的要求,而不是
recordSCore
的签名。好吧……那么,如果我这样做的话将其改为int,并切换一些内容,我可以让它正确记录分数,但打印功能中断…上载新代码?啊,我没有意识到关于删除的事情。谢谢!关于分数的事情…我的导师希望它设置为NULL,因此我必须:(-但是你提供的关于指针对null无效的信息是有用的,谢谢你!但是,在recordScore下,当它不在那里时,它会正确打印…当它到达printScore时,它会在过程中以某种方式变回null,或者可能只是垃圾,或者其他东西,我不能完全确定。如果你谈到更改部分,当您通过值而不是指针传递int时,将传递abc的副本。该副本将在函数结束后被删除。因此,稍后它将成为垃圾值。