繁体   English   中英

复制构造函数和赋值运算符问题

[英]Copy Constructor and Assignment Operator Issues

我正在为作业分配一个二进制链接列表,该列表仅存储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;
}

我的逻辑对这些有误吗? 有人请帮忙!

PS我已经测试了我的set_bit(b,d)和其他方法,我知道这些是唯一的混乱,因为当我尝试“ Binary b3(b2)”或“ Binary b3 = b2”时,程序停止在那点,然后说:“分配1.exe中0x00DC4B18的未处理异常:0xC0000005:访问冲突读取位置0xCCCCCCD0”。

编辑:我也有一个默认的构造函数:Binary(){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;
}
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); 
    }
}

我想通了,谢谢大家的帮助。 我发现了我的问题。 正如有人指出的那样,我相信在复制构造函数中,还没有像其他构造函数中那样声明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;
    }
}

定义构造函数后,编译器将不会为您生成默认的构造函数,这意味着您无法进行Binary clone; 如果尚未定义Binary::Binary()构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM