2013-10-13 131 views
0

我知道指針是被討論了很多東西。我已經做了大量的研究來嘗試解決這個問題,但是一切都導致我陷入死衚衕。C++通過main函數中的類函數傳遞指針

我有一個任務是要求我創建一個記錄單個測試分數的類。如果測試分數已經被記錄並且新分數較高,則覆蓋它。如果它已被記錄並且新分數較低,則什麼也不做。如果沒有被記錄,記錄它。

這是我到目前爲止有:

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

指針是一些很新的給我...我看着他們,看着他們,看着他們,多一些,但我似乎總是讓他們錯了。

知道了,我知道我的recordScore函數可能做了非常錯誤的事情,但我不知道是什麼。

我現在的主要問題是,firstScore運行良好(耶!我得到了正確的......也許)但是,secondScore不會記錄分數。我嘗試了幾種不同的方法。

  1. 我把int abc = 0;這個測試已經採取:以上INT主要()

    • 當我打電話recordScore
    • 編譯,當我打電話printScore
      • 輸出顯示崩潰編譯和運行良好!按任意鍵繼續......(崩潰)
  2. 我把INT ABC = 0;內中的int main()的,但任何事情之前

    • 當我打電話recordScore事情之前被輸出到控制檯

這也崩潰,如果我的INT主()是這樣的崩潰:

int main() 
{ 
    int abc = 0; 

    testScore firstScore; 
    firstScore.printScore(cout); 


    system("PAUSE"); 
    return 0; 
} 

而且我不知道爲什麼TT

我也有TR IED:

聲明

int *myTestScore; 
myTestScore = new int; 
*myTestScore = 83; 

裏面的main(),但通過別的,並通過myTestScore到recordScore前:

&myTestScore 

編譯錯誤:調用「testScore沒有匹配功能:: recordScore(INT **);在secondScore.recordScore線上的 。

*myTestScore 

編譯錯誤:從 '詮釋' 對secondScore '詮釋*' 無效的轉換。recordScore線。

myTestScore 

沒有編譯錯誤,死機當它運行之前什麼是輸出到控制檯

我曾嘗試聲明:

int *myTestScore = 83; 

裏的任何東西之前,INT主要()其他 編譯錯誤:對int * myTestScore = 83行的'int'無效轉換爲'int *' 。

我也嘗試過將recordScore改爲使用&的*和*的各種方法,並且都沒有改變這兩者的組合。

我現在沒有想法嘗試的東西,即使經過研究,我也無法想出任何東西。我試着問我的教授(現在一週,這是在線課程),給她打電話,給她發電子郵件,但她沒有回答我的任何問題,甚至沒有要求開會。

我覺得有一些簡單的東西我不是在這裏抓的,我非常感謝任何人都可以幫助我解決這個問題。

非常感謝你的時間。


變化:

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

輸出: 這個測試沒有被搶走! 按任意鍵繼續......


最終工作產品:

// 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), testTaken(false) 
{ 
    // 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) 
    { 
       score = new int; 
       testTaken = true; 
       *score = *myScore; 
    } 
    else if(testTaken == true && *myScore > *score) 
    { 
       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) 
    { 
      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 main() 
{ 
    int abc = 83; 

    testScore firstScore; 
    firstScore.printScore(cout); 

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

    abc = 78; 
    secondScore.recordScore(&abc); 
    secondScore.printScore(cout); 

    abc = 92; 
    secondScore.recordScore(&abc); 
    secondScore.printScore(cout); 

    system("PAUSE"); 
    return 0; 
} 

太感謝你了,其實我是從這個頗有幾分瞭解到,和一些新的術語太:) :)

+2

*聲明一個函數來記錄測試分數,參數將是**整數***。你聲明它需要一個指向一個整數的指針。讀你的問題,我建議你停下來,喘口氣,重讀你的材料指針。如果你寫'int * myScore = 83;'並且需要問什麼是錯誤的,這意味着你需要學習更多。 – jrok

+0

梅爾,在開始時她曾說過://申報記錄測試分數的班級 //數據將是指向一個整數的指針,而不是一個整數 –

+0

這是班級的要求,而不是「 recordSCore'。 – jrok

回答

1

主要問題是,在默認的構造函數中,你指定NULL來評分,所以指針會指向無效的內存。所以,當你調用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指針(這不會導致錯誤),並且用於score的內存未被釋放,導致內存泄漏

+0

啊,我沒有意識到有關刪除的事情。謝謝! 只要得分的事情... 我的老師希望它設置爲NULL,所以我必須:( - 但你給指針無效的信息爲空是有用的,謝謝你,以及! 但是,根據recordScore,當它在那裏,它打印正確... 它是什麼時候它得到printScore它以某種方式得到改變回到NULL,或者只是爲了垃圾,或什麼,我不完全確定。更新代碼 –

+0

如果你正在談論Changes部分,當你通過一個int值而不是一個指針傳入時,abc的一個副本將被傳遞,並且該副本將在函數結束後被刪除。一個垃圾值稍後。 – xorguy