2013-03-08 87 views
0

我正在爲僅存儲1位度數的作業分配創建二進制鏈接列表。我可以獲得最高級別,在二進制列表中的任意位置設置位,並返回某個特定級別的位,但由於某種原因,我在創建複製構造函數和賦值(=)操作符時遇到了最大的麻煩。這裏是我的代碼:複製構造函數和賦值操作符問題

// copy constructor 
// creates a new linked list where the contents are a deep copy of the provided list 
Binary::Binary(const Binary &b) 
{ 
    Binary clone; 
    for(BinaryNode* current_other = b.firstTerm; current_other != nullptr; current_other = current_other->next) 
    { 
     clone.set_bit(1, current_other->degree); 
    } 
} 

// assignment operator 
// sets the current link list to be a deep copy of the provided list. 
// make sure to check if assigning to itself, and make sure to free old memory 
// before making the copy. 
Binary& Binary::operator=(const Binary &other) 
{ 
    Binary clone; 
    for(BinaryNode* current_other = other.firstTerm; current_other != nullptr; current_other = current_other->next) 
    { 
     clone.set_bit(1, current_other->degree); 
    } 
    return clone; 
} 

我的邏輯在這些上是否有缺陷?有人請幫忙!

P.S.我已經測試了我的set_bit(b,d)和其他方法,我知道這些是唯一搞亂的,因爲當我嘗試「Binary b3(b2)」或「Binary b3 = b2」時,程序停止指出並且「分配1.exe中的0x00DC4B18未處理的異常:0xC0000005:訪問衝突讀取位置0xCCCCCCD0」。

編輯:我有一個默認的構造,以及: 二進制(){firstTerm = nullptr;}

編輯編輯:

輸出:

TESTING DEFAULT CONSTRUCTOR 
    The binary number b1 is empty. 

    TESTING GET AND SET METHODS 
    The highest bit of binary number b1 is 5. 
    The bit of binary number b1 at degree 5 is 1. 
    The bit of binary number b1 at degree 2 is 0. 
    The bit of binary number b1 at degree 1 is 0. 

    TESTING PARAMETER CONSTRUCTOR 
    The bit of binary number b1 at degree 2 is 1. 
    The bit of binary number b1 at degree 0 is 1. 
    The bit of binary number b1 at degree 1 is 0. 

    TESTING COPY CONSTRUCTOR 
    B2 = 101 
    B3 = _ 

Unhandled exception at 0x00C04B18 in Assignment 1.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0. 

儀代碼:

#include <iostream> 
#include "binary.h" 

using namespace std; 

int main (void) 
{ 
    // test default constructor 
    Binary b1; 
    cout << "TESTING DEFAULT CONSTRUCTOR" << endl; 
    if (b1.get_degree() == -1) 
     cout << "\tThe binary number b1 is empty." << endl; 
    else 
     cout << "\tThe binary number b1 is NOT empty. (INCORRECT)" << endl; 

    // test get_bit, set_bit, and get_degree 
    cout << "\nTESTING GET AND SET METHODS" << endl; 
    b1.set_bit(1, 2); 
    b1.set_bit(1, 5); 
    b1.set_bit(1, 0); 
    b1.set_bit(0, 2); 
    if (b1.get_degree() == 5) 
     cout << "\tThe highest bit of binary number b1 is 5." << endl; 
    else 
     cout << "\tThe highest bit of binary number b1 is NOT 5. (INCORRECT)" << endl; 
    if (b1.get_bit(5) == 1) 
     cout << "\tThe bit of binary number b1 at degree 5 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b1 at degree 5 is 0. (INCORRECT)" << endl; 
    if (b1.get_bit(2) == 0) 
     cout << "\tThe bit of binary number b1 at degree 2 is 0." << endl; 
    else 
     cout << "\tThe bit of binary number b1 at degree 2 is 1. (INCORRECT)" << endl; 
    if (b1.get_bit(1) == 0) 
     cout << "\tThe bit of binary number b1 at degree 1 is 0." << endl; 
    else 
     cout << "\tThe bit of binary number b1 at degree 1 is 1. (INCORRECT)" << endl; 

    // test parameter constructor 
    cout << "\nTESTING PARAMETER CONSTRUCTOR" << endl; 
    Binary b2(5); 

    if (b2.get_bit(2) == 1) 
     cout << "\tThe bit of binary number b2 at degree 2 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b2 at degree 2 is 0. (INCORRECT)" << endl; 
    if (b2.get_bit(0) == 1) 
     cout << "\tThe bit of binary number b2 at degree 0 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b2 at degree 0 is 0. (INCORRECT)" << endl; 
    if (b2.get_bit(1) == 0) 
     cout << "\tThe bit of binary number b2 at degree 1 is 0." << endl; 
    else 
     cout << "\tThe bit of binary number b2 at degree 1 is 1. (INCORRECT)" << endl; 

    // test copy constructor 
    cout << "\nTESTING COPY CONSTRUCTOR" << endl; 
    cout << "B2= " << b2 << endl; 
    b2.set_bit(1,1); 
    Binary b3(b2); 
    cout << "B3= " << b3 << endl; 
    b2.set_bit(1, 1); 
    cout << "B2= " << b2 << endl; 
    cout << "B3= " << b3 << endl; 
    if (b3.get_bit(2) == 1) 
     cout << "\tThe bit of binary number b3 at degree 2 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b3 at degree 2 is 0. (INCORRECT)" << endl; 
    if (b3.get_bit(0) == 1) 
     cout << "\tThe bit of binary number b3 at degree 0 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b3 at degree 0 is 0. (INCORRECT)" << endl; 
    if (b3.get_bit(1) == 0) 
     cout << "\tThe bit of binary number b3 at degree 1 is 0." << endl; 
    else 
     cout << "\tThe bit of binary number b3 at degree 1 is 1. (INCORRECT)" << endl; 

    // test assignment operator 
    cout << "\nTESTING ASSIGNMENT OPERATOR" << endl; 
    b2 = b3; 
    b3.set_bit(1, 1); 

    if (b2.get_bit(2) == 1) 
     cout << "\tThe bit of binary number b2 at degree 2 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b2 at degree 2 is 0. (INCORRECT)" << endl; 
    if (b2.get_bit(0) == 1) 
     cout << "\tThe bit of binary number b2 at degree 0 is 1." << endl; 
    else 
     cout << "\tThe bit of binary number b2 at degree 0 is 0. (INCORRECT)" << endl; 
    if (b2.get_bit(1) == 0) 
     cout << "\tThe bit of binary number b2 at degree 1 is 0." << endl; 
    else 
     cout << "\tThe bit of binary number b2 at degree 1 is 1. (INCORRECT)" << endl; 

    // test convert 
    cout << "\nTESTING CONVERT METHOD" << endl; 
    if (b1.convert() == 33) 
     cout << "\tThe decimal value of binary number b1 is 33." << endl; 
    else 
     cout << "\tThe decimal value of binary number b1 is NOT 33. (INCORRECT)" << endl; 

    // test output operator 
    cout << "\nTESTING OUTPUT OPERATOR" << endl; 
    cout << "\tThe binary number b1 is " << b1 << endl; 
    cout << "\tThe number b1 should be 100001" << endl; 

    // test addition 
    cout << "\nTESTING ADDITION OPERATOR" << endl; 
    Binary b4 = b2 + b3; 

    if (b4.convert() == 12) 
     cout << "\t101 + 111 = 1100." << endl; 
    else 
     cout << "\t101 + 111 != 1100. (INCORRECT)" << endl; 

    // test subtraction 
    cout << "\nTESTING SUBTRACTION OPERATOR" << endl; 
    Binary b5(b1 - b2); 

    if (b5.convert() == 28) 
     cout << "\t100001 - 101 = 11100." << endl; 
    else 
     cout << "\t100001 - 101 != 11100. (INCORRECT)" << endl; 

    // test multiplication 
    cout << "\nTESTING MULTIPLICATION OPERATOR" << endl; 
    Binary b6 = b3 * b2; 

    if (b6.convert() == 35) 
     cout << "\t111 * 101 = 100011." << endl; 
    else 
     cout << "\t111 * 101 != 100011. (INCORRECT)" << endl; 

    system("pause"); 
} 

binary.h:

#ifndef _BINARY_H_ 
#define _BINARY_H_ 

#include <iostream> 

class Binary { 
private: 
    struct BinaryNode { 
     int degree; 
     BinaryNode* next; 
     BinaryNode(int d, BinaryNode* n): degree(d),next(n) {} 
    }; 
    BinaryNode *firstTerm; 

public: 
    // default constructor 
    Binary() {firstTerm = nullptr;} 

    // constructor 
    // takes a value representing a decimal number and creates 
    // the binary linked list representation of it. 
    Binary(int x); 

    // sets the term with degree d and bit b 
    // notice a node is created if bit is 1 AND a node 
    // for that degree doesn't exist, or the node is removed 
    // if the bit is 0 AND the node with that degree already exists 
    void set_bit(int b, int d); 

    // returns one if a term with degree d exists, zero otherwise 
    int get_bit(int d) const; 

    // returns the decimal integer representation of the binary number. 
    int convert() const ; 

    // returns the highest degree of any term in the binary number 
    // returns -1 if the the list is empty. 
    int get_degree() const; 

    // destructor 
    // make sure that all memory is returned (freed up) correctly 
    ~Binary(); 

    // copy constructor 
    // creates a new linked list where the contents are a deep copy of the provided list 
    Binary(const Binary &b); 

    // assignment operator 
    // sets the current link list to be a deep copy of the provided list. 
    // make sure to check if assigning to itself, and make sure to free old memory 
    // before making the copy. 
    Binary& operator=(const Binary &other); 

    // prints the binary number to the output stream o 
    // please use like:  10001101 
    // terms must be printed in descending order of degree 
    friend std::ostream& operator<<(std::ostream &o, const Binary &b); 

    // returns a new binary number representing the addition of 2 provided binary numbers. 
    // do NOT simply convert the numbers to decimal using convert(),add them, 
    // then convert back to binary. 
    friend Binary operator+(const Binary &b1, const Binary &b2); 

    // returns a new binary number representing the subtraction 
    // of 2 provided binary numbers. can assume b1 will always be 
    // larger than b2. 
    // do NOT simply convert the numbers to decimal using convert(),subtract them, 
    // then convert back to binary. 
    friend Binary operator-(const Binary &b1, const Binary &b2); 

    // returns a new binary number representing the multiplication 
    // of 2 provided binary numbers. 
    // do NOT simply convert the numbers to decimal using convert(),multiply them, 
    // then convert back to binary. 
    friend Binary operator*(const Binary &b1, const Binary &b2); 

}; 

std::ostream& operator<<(std::ostream &o, const Binary &b); 

Binary operator+(const Binary &b1, const Binary &b2); 
Binary operator-(const Binary &b1, const Binary &b2); 
Binary operator*(const Binary &b1, const Binary &b2); 

#endif 

binary.cpp:

#include "binary.h" 
using namespace std; 

// constructor 
// takes a value representing a decimal number and creates 
// the binary linked list representation of it. 
Binary::Binary(int x) 
{ 
    firstTerm = nullptr; 
    int deg = 0; 
    int n = x; 
    while (n != 0) 
    { 
     set_bit(n%2, deg); 
     n = n/2; 
     ++deg; 
    } 
} 

// sets the term with degree d and bit b 
// notice a node is created if bit is 1 AND a node 
// for that degree doesn't exist, or the node is removed 
// if the bit is 0 AND the node with that degree already exists 
void Binary::set_bit(int b, int d) 
{ 
    if (b == 1) 
    { 
     if (firstTerm == nullptr || d == 0) 
      { 
       firstTerm = new BinaryNode(d, firstTerm); 
      } 

     else 
      { 
       BinaryNode *current, *prev = firstTerm; 
       for(current = firstTerm; current != nullptr; current = current->next) 
       { 
        if (current->next == nullptr) 
        { 
         current->next = new BinaryNode(d, nullptr); 
         break; 
        } 
        else if (current->degree == d) 
        { 
         prev->next = new BinaryNode (d, current->next); 
         delete current; 
         break; 
        } 
        else if(current->degree > d) 
        { 
         prev->next = new BinaryNode (d, current); 
         break; 
        } 
        prev = current; 
       } 
      } 
    } 
    else 
    { 
     BinaryNode *current, *prev = firstTerm; 
     for(current = firstTerm; current != nullptr; current = current->next) 
     { 
      if (current->degree == d) 
      { 
       prev->next = current->next; 
       delete current; 
       break; 
      } 
      prev = current; 
     } 
    } 
} 

// returns one if a term with degree d exists, zero otherwise 
int Binary::get_bit(int d) const 
{ 
    for (BinaryNode *current = firstTerm; current != nullptr; current = current->next) 
    { 
     if (current == nullptr) 
      break; 
     if (current->degree == d) 
      return 1; 
    } 
    return 0; 
} 

// returns the decimal integer representation of the binary number. 
int Binary::convert() const 
{ 
    int sum = 0; 
    for (BinaryNode* current = firstTerm; current != nullptr; current = current->next) 
    { 
     sum = sum + (int)pow(2,current->degree); 
    } 
    return sum; 
} 

// returns the highest degree of any term in the binary number 
// returns -1 if the the list is empty. 
int Binary::get_degree() const 
{ 
    if (firstTerm == nullptr) 
     {return -1;} 
    else 
    { 
     BinaryNode *current; 
     for (current = firstTerm; current->next != nullptr; current = current->next); 

     return current->degree; 
    } 
} 

// destructor 
// make sure that all memory is returned (freed up) correctly 
Binary::~Binary() 
{ 
    BinaryNode* tmp; 
    for(BinaryNode* current = firstTerm; current != nullptr; current = tmp) 
    { 
      tmp = current->next; 
      delete current; 
    } 
} 

// copy constructor 
// creates a new linked list where the contents are a deep copy of the provided list 
Binary::Binary(const Binary &b) 
{ 
    for(BinaryNode* current_other = b.firstTerm; current_other != nullptr; current_other = current_other->next) 
    { 
     set_bit(1, current_other->degree); 
    } 
} 

// assignment operator 
// sets the current link list to be a deep copy of the provided list. 
// make sure to check if assigning to itself, and make sure to free old memory 
// before making the copy. 
Binary& Binary::operator=(const Binary &other) 
{ 
    Binary clone; 
    for(BinaryNode* current_other = other.firstTerm; current_other != nullptr; current_other = current_other->next) 
    { 
     clone.set_bit(1, current_other->degree); 
    } 
    return clone; 
} 

// prints the binary number to the output stream o 
// please use like:  10001101 
// terms must be printed in descending order of degree 
std::ostream& operator<<(std::ostream &o, const Binary &b) 
{ 
    for(int i = b.get_degree(); i >= 0; --i) 
    { 
     o << b.get_bit(i); 
    } 
    return o; 
} 

// returns a new binary number representing the addition of 2 provided binary numbers. 
// do NOT simply convert the numbers to decimal using convert(),add them, 
// then convert back to binary. 
Binary operator+(const Binary &b1, const Binary &b2) 
{ 
    int l = b1.get_degree(); 
    if (b1.get_degree() < b2.get_degree()) 
    { 
     l = b2.get_degree(); 
    } 
    int i, c = 0; 
    Binary sum; 
    for (i = 0; i <= l; ++i) 
    { 
     sum.set_bit(((b1.get_bit(i)^b2.get_bit(i))^c), i); //get sum (A XOR B XOR C) 
     c = ((b1.get_bit(i) & b2.get_bit(i)) | (b1.get_bit(i) &c)) | (b2.get_bit(i) & c); //get carry bit (AB + BC + CA) 
    } 
    sum.set_bit(c, i); 
    return sum; 
} 

// returns a new binary number representing the subtraction 
// of 2 provided binary numbers. can assume b1 will always be 
// larger than b2. 
// do NOT simply convert the numbers to decimal using convert(),subtract them, 
// then convert back to binary. 
Binary operator-(const Binary &b1, const Binary &b2) 
{ 
    Binary one = Binary(1); 
    Binary inv, two, result, fresult; 
    int i, l = b2.get_degree() + 1; 
    for(i = 0; i <= l; ++i) 
    { 
     if (b2.get_bit(i) == 1) 
      inv.set_bit(0,i); 
     else 
      inv.set_bit(1,i); 
    } 
    two = inv + one; 
    result = two + b1; 
    if (b1.get_degree() > l) 
    { 
     l = b1.get_degree(); 
    } 
    for (l; l >= 0; l--) 
    { 
     fresult.set_bit(result.get_bit(l), l); 
    } 
    return (fresult); 
} 

// returns a new binary number representing the multiplication 
// of 2 provided binary numbers. 
// do NOT simply convert the numbers to decimal using convert(),multiply them, 
// then convert back to binary. 
Binary operator*(const Binary &b1, const Binary &b2) 
{ 
    Binary prod = b1; 
    for (int i = 1; i < b2.convert(); ++i) 
    { 
     prod = prod + b1; 
    } 
    return prod; 
} 
+0

我相信對於operator =使用這個指針而不是製作一個新的Binary並克隆它。 – 2013-03-08 19:04:00

+0

你是否定義了一個默認構造函數? (一個不帶任何參數的構造函數) – Roberto 2013-03-08 19:07:43

+0

我們需要您的完整課程來幫助您... – Roberto 2013-03-08 21:02:51

回答

1

我想通了,謝謝大家的幫助。我想出了我的問題。在複製構造函數中,正如有人指出的那樣,我相信,我還沒有聲明firstTerm,因爲我必須在其他構造函數中聲明。最後的代碼最終爲:

Binary::Binary(const Binary &b) 
{ 
    firstTerm = nullptr; //construct firstTerm 
    for(BinaryNode* current_other = b.firstTerm; current_other != nullptr; current_other = current_other->next) 
    //set a node pointer = to b's firstTerm then go through b's list, setting each bit and degree to the new list 
    { 
     set_bit(1, current_other->degree); //only 1 bits exist in this list, so you'll only set one bits at each degree 
    } 
} 

在賦值運算符,我不是第一次破壞當前目錄,如果需要的話,或者確保它沒有被複制到自身。另外,我在錯誤的地方有&。最後的代碼結束爲:

Binary &Binary::operator=(const Binary &other) 
{ 
    if(this != &other) //make sure it isn't copying to itself 
    { 
     if (this->get_degree() != -1) //if the Binary list isn't empty, destruct it 
     { 
      this->~Binary(); 
     } 
     firstTerm = nullptr; //construct firstTerm 
     for(BinaryNode* current_other = other.firstTerm; current_other != nullptr; current_other = current_other->next) 
     //set a node pointer = to other's firstTerm then go through other's list, setting each bit and degree to the new list 
     { 
      set_bit(1, current_other->degree); //only 1 bits exist in this list, so you'll only set one bits at each degree 
     } 

     return *this; 
    } 
} 
3
Binary::Binary(const Binary &b) 
{ 
    Binary clone; 
    for(BinaryNode* current_other = b.firstTerm; current_other != nullptr; current_other = current_other->next) 
    { 
     clone.set_bit(1, current_other->degree); 
    } 
} 

您創建一個對象稱爲clone,設置其位,然後把它扔掉。這看起來不正確。也許你的意思是:

Binary::Binary(const Binary &b) 
{ 
    for(BinaryNode* current_other = b.firstTerm; current_other != nullptr; current_other = current_other->next) 
    { 
     set_bit(1, current_other->degree); 
    } 
} 
+0

我也試過,但它也不起作用... – 2013-03-08 19:17:46

+0

「它不起作用」不是一個有幫助的問題描述。它是否編譯?它運行嗎?你期待什麼結果?你得到了什麼? (你也有一個與'operator ='類似的問題 - 它不會修改它被調用的對象,這是這樣的操作符通常會做的。) – 2013-03-08 19:18:46

+0

對不起,我急着去工作。當我以另一種方式擁有它時,它會給我帶來同樣的錯誤。該程序編譯,但是當我嘗試對複製的二進制列表執行任何操作時,它會在原始文章中發佈「訪問衝突讀取」錯誤。 例如,在main()中,我有: Binary b3(b2); cout << b3 << endl; 在這一點上,在輸出,它打破了,但事先預先工作。我會在上面發佈我的整個代碼。 – 2013-03-09 03:34:52

0

一個一旦你定義構造函數,編譯器將不會爲你生成一個默認的構造,這意味着你不能做Binary clone;如果你還沒有定義的Binary::Binary()構造。

+0

我也有一個默認構造函數: Binary(){firstTerm = nullptr;} – 2013-03-08 19:14:29

相關問題