Thread: Overloading assignment operator

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    45

    Overloading assignment operator

    Hi everyone, I'm writing a part of my program that compares three objects of class IntArray:

    Code:
    IntArray IntArray::operator=(IntArray h){
        if (len != h.len){
            hault();
        }
        else {
            IntArray temp(len);
            for (int i = 0; i <= len; i++){
                temp.arr[i] = h.arr[i];
            }
            return temp;
        }
    }
    I overloaded the assignment operator so that the arrays within each class object can be compared. It works perfectly when comparing two classes (a = b), however when I try comparing three (a = b = c) the program gives me an unhandled exception error. I think it might have something to do with memory allocation?

    Thanks for any help! Let me know if you need to see the rest of my program...
    -Ryan

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Okay stop. There is an operator for the type of comparison you intend to make, called the equality operator: ( == ) overload that one. While you can do what you want to do, I advise against it.

    Normally to compare three objects, such that they are all the same, you need

    a == b && a == c, or something logically equivalent.

    a = b = c, copies c, and assigns those copies to a and b. It's not a comparison. So which do you want to do?

  3. #3
    Registered User
    Join Date
    Mar 2012
    Posts
    45
    Ahh I'm sorry I didn't mean to say compare, I am trying to set the three objects equal to each other.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Ok well, you will probably have to rewrite the entire operator. The code that you have now, AFAICT, makes no changes to the current object. To make one object like another object, you have to make changes to the current object.

    I see that you make a new object called temp, that is actually a good start. I would take it a step further:
    Code:
    IntArray temp( h ); // copy construct new temp object from h
    Now temp is like h in every way; the loop that copied the elements should be in that copy constructor as well. Unless there was an exception, we continue with:
    Code:
    std::swap(temp.arr, this->arr);
    std::swap(temp.len, this->len);
    ...
    We swap out all the old members, storing them in temp. When temp goes out of scope, it will be destroyed by the destructor, removing the old members, and h is not modified in the process. In normal design, you would write this bit of code in a member function called swap. As we see later it just makes things easier. But quickly, just a note about why things are done this way: we don't modify the current object until everything is prepared to do so. Then we continue the more complicated task in a way that doesn't raise exceptions. This means we can guarantee that there were no changes to the current object in the event of an exception occurring early on (like running out of memory).

    Finally, if you want make three objects all the same on one line, you have to have a prototype like this.
    Code:
    IntArray& operator = (const IntArray& h);
    // feeds into the other operator, consider the following:
    // a.operator=(b.operator=(c)));
    I hope that comment is clear, because it explains why chaining works.

    Now we have the "final" code:
    Code:
    IntArray& operator = (const IntArray& h)
    {
       IntArray temp(h);
       temp.swap(*this);
       return *this;
    }
    Quite simple, but you will have to make it work and debug on your own. I really don't think my little post explained everything, but I tried.
    Last edited by whiteflags; 10-26-2012 at 06:14 PM.

  5. #5
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    The overloaded operator returns a local object.But when the function terminates local object die in normal situation.So a=b will call the overloaded operator.When what was returned is going to be perform this operation
    Code:
     whatIsReturned = c
    but whatIsReturned is de-allocated.

    If you want something to be alive after the function terminates,a solution would be to use keyword new to create the object inside the function

    -now i saw your second post.
    Last edited by std10093; 10-26-2012 at 06:06 PM.

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    45
    Thanks for all the info! That all makes sense to me (except for the *this pointer, which for whatever reason always confuses me) however, I apologize I left out the fact that I need to keep each object the same and only copy the .arr portion. This is my class:

    Code:
    class IntArray {
    private:
        int *arr;
        int lo;                    //low legal index
        int hi;                    //high legal index
        int first;                //alias low index
        int second;                //alias high index
        int len;                //length of array
        string name;            //name of IntArray object
    public:
        IntArray();                    //default constructor
        IntArray(int);                //creates array of int size
        IntArray(int, int);            //creates an array appearing as [int] to [int] (not actual indices)
        IntArray(const IntArray&);    //copy constructor
        ~IntArray();                //destructor
    
        int high();                    //returns high legal index
        int low();                    //returns low legal index
        string setName(string);        //assigns a string to name
    
        IntArray operator+(IntArray);
        int& operator[](const int);
        IntArray operator=(IntArray);
        void operator+=(IntArray);
        friend ostream& operator<<(ostream&, IntArray&);
        int operator==(IntArray);
        int operator!=(IntArray);
    };
    So what I need to do is copy only the 'arr' to each object, leaving the rest of the properties the same. So could I still use your method by creating a new copy constructor that copies only the 'arr'? As you can see in the class above I already have a copy constructor, which I have written to copy nearly all properties...Can I create another?

    Thanks again!

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You really need to learn to pass by const-reference. You should also not remove parameter names
    E.g.
    Code:
    IntArray operator = (const IntArray &other);
    Luckily you used it for your copy-constructor otherwise you'd get infinite recursion! Use it elsewhere too. Use it for that string parameter to setName.

    Then learn about const methods. e.g.
    Code:
    int high() const;
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by ryanmcclure4 View Post
    Thanks for all the info! That all makes sense to me (except for the *this pointer, which for whatever reason always confuses me) however, I apologize I left out the fact that I need to keep each object the same and only copy the .arr portion. This is my class:

    So what I need to do is copy only the 'arr' to each object, leaving the rest of the properties the same.
    That is a weird requirement. Why? Imagine two totally different objects: a, b.
    You do a = b;
    If you only copy the arr portion, the rest of a will be like the old a instead of b.
    So could I still use your method by creating a new copy constructor that copies only the 'arr'? As you can see in the class above I already have a copy constructor, which I have written to copy nearly all properties...Can I create another?

    Thanks again!
    No, that probably won't work. What you want to do is not assignment. Make a member function that does this.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Sorry, the above should have been:
    Code:
    IntArray& operator = (const IntArray &other);
    operator == and operator != should also return bool, not int.

    Perhaps you could include some updated code with your next post, including your copy-constructor, corrected assignment operator, and the new operator ==.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Is there a reason you do not use std::vector instead of pointers for dynamic arrays?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Mar 2012
    Posts
    45
    iMalc - I read up on passing by const-reference and from what I understand the reason for doing this is so that the compiler doesn't need to make a copy of the object in order to use it in the function (saving space), while at the same time it cannot alter the object? So I should be doing this whenever a function is passing an object of the class type? Or do I only need to do use it when it is also returning the class type? I hope this makes sense...

    As for const methods, If I have a function in a class that doesn't have any parameters I should write it as you did in your example so that the function is banned from altering any member variables?

    Here is my class (slightly altered):
    Code:
    class IntArray {
    private:
        int *arr;
        int lo;                    //low legal index
        int hi;                    //high legal index
        int first;                //alias low index
        int second;                //alias high index
        int len;                //length of array
        string name;            //name of IntArray object
    public:
        IntArray();                    //default constructor
        IntArray(int num);                //creates array of int size
        IntArray(int a, int b);            //creates an array appearing as [int] to [int] (not actual indices)
        IntArray(const IntArray&);    //copy constructor
        ~IntArray();                //destructor
    
        int high() const;                    //returns high legal index
        int low() const;                    //returns low legal index
        string& setName(const string& n);        //assigns a string to name
    
        IntArray operator+(IntArray h);
        int& operator[](const int i);
        IntArray& operator=(const IntArray &h);
        void operator+=(IntArray h);
        friend ostream& operator<<(ostream& os, IntArray& h);
        int operator==(IntArray h);
        int operator!=(IntArray h);
    };
    And the .cpp file for the class:
    Code:
    #include <iostream>
    #include <string>
    #include "IntArray.h" 
    
    using namespace std;
    
    void hault(){
        cout << "Error! Your arrays are not the same size!" << endl;
    }
    
    IntArray::IntArray(){
        first = 1;
        second = 10;
        hi = 9;
        lo = 0;
        arr = new int[10];
    }
    
    IntArray::IntArray(int num){
        first = 1;
        second = num;
        hi = num;
        lo = 0;
        arr = new int[num];
    }
    
    IntArray::IntArray(int a, int b){
        first = a;
        second = b;
    
        if (first > second){
            cout << "Woah there! The first index must be smaller than the second index!" << endl;
        }
        else if (first == second){
            arr = new int[1];
            len = 1;
        }
        else {
            len = second - first;
            arr = new int[len];
        };
        hi = len;
        lo = 0;
    }
    
    IntArray::IntArray(const IntArray& h){
        lo = h.lo;
        hi = h.hi;
        first = h.first;
        second = h.second;
        len = h.len;
        arr = h.arr;
    }
    
    int IntArray::high() const{
        return hi;
    }
    
    int IntArray::low() const{
        return lo;
    }
    
    string& IntArray::setName(const string& n){
        name = n;
        return name;
    }
    
    IntArray IntArray::operator+(IntArray h){
        if (len != h.len){
            hault();
        }
        else {
            IntArray temp(hi);
            for (int i = lo; i <= hi; i++){
                temp.arr[i] = arr[i] + h.arr[i];
            }
            return temp;
        }
    }
    
    IntArray& IntArray::operator=(const IntArray& h){
        if (len != h.len){
            hault();
        }
        else {
            IntArray temp(len);
            for (int i = 0; i <= len; i++){
                temp.arr[i] = h.arr[i];
            }
            return temp;
        }
    }
    
    int& IntArray::operator[](const int i){
        return arr[i];
    }
    
    void IntArray::operator+=(IntArray h){
        if (len != h.len)
            hault();
        else {
            for (int i = 0; i <= len; i++){
                arr[i] += h.arr[i];
            }
        }
    }
    
    ostream& operator<<(ostream& os, IntArray& h){
        int count = 0;
        for(int i = h.first; i <= h.second; i++){
            os << h.name << "[" << i << "] = " << h.arr[count] << endl;
            count++;
        }
        return os;
    }
    
    int IntArray::operator==(IntArray h){
        int equality = 1;
        if (len != h.len)
            equality = 0;
        else if (len == h.len) {
            for (int i = lo; i <= hi; i++){
                if (arr[i] != h.arr[i])
                    equality = 0;
            }
        }
        return equality;
    }
    
    int IntArray::operator!=(IntArray h){
        int equality = 0;
        if (len != h.len)
            equality = 1;
        else if (len == h.len) {
            for (int i = lo; i <= hi; i++){
                if (arr[i] != h.arr[i])
                    equality = 1;
            }
        }
        return equality;
    }
    
    IntArray::~IntArray(){
    }
    Whiteflags - This is an assignment for my class, and the point of the program is to allow the user to create an array with any indices that they would like (-3, 9) etc...which are obviously illegal. So the class creates an object that has an array which appears to use these indices like (-3, 9), but actually uses (0, 12) to store the numbers.

    There is a driver program that does a series of tests whether or not I overloaded the operators correctly (which was the point of this assignment). One of the requirements was that when overloading the assignment operator, we were to make it so that it would keep the "fake" indices of the object's array but copy the values inside the array. So the assignment operator is only changing one part of the class.

    As you can see I didn't change much about the overloaded assignment operator because since I changed it to pass by const-reference it started working. The only problem with it now is that, in the driver program, it assigns three objects to each other (j = k = l) which all have arrays of the same size. In my assignment operator it checks first to see whether or not the objects are of the same size, and when I run the program it is throwing my halut(); function and says they are not equal...

    iMalc - I did not use bool because the requirement for that operator was to return a non zero value if equal, and a zero if not equal.

    Elysia - I have not learned about vectors yet...although the pointer seems to be doing the job at the moment. I'll look into that though.

    If none of this makes sense, here is the driver program and header so that you can run it:
    Code:
    // iadrv.cpp - driver program for testing IntArray class
    
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <stdlib.h>
    #include "iadrv.h"
    
    using namespace std;
    
    ofstream csis;
    
    int main() {
        csis.open("csis.txt");
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
        test7();
        test8();
        test9();
        test10();
        test11();
        test12();
        test13();
        test14();
        test15();
        test16();
        test17();
        test18();
        test19();
        test20();
        csis.close();
    }
    
    void test1() {
        cout << "1. Array declared with single integer: IntArray a(10);" << endl << endl;
        csis << "1. Array declared with single integer: IntArray a(10);" << endl << endl;
        IntArray a(10);
        for(int i = a.low(); i <= a.high(); i++)
            a[i] = i * 10;
        a.setName("a");
        cout << a << endl;
        csis << a << endl;
        wait();
    }
    
    void test2() {
        cout << "2. Array declared with two integers: IntArray b(-3, 6);" << endl << endl;
        csis << "2. Array declared with two integers: IntArray b(-3, 6);" << endl << endl;
        IntArray b(-3, 6);
        for(int i = b.low(); i <= b.high(); i++)
            b[i] = i * 10;
        b.setName("b");
        cout << b << endl;
        csis << b << endl;
        wait();
    }
    
    void test3() {
        cout << "3. Array declared with two integers: IntArray c(6, 8);" << endl << endl;
        csis << "3. Array declared with two integers: IntArray c(6, 8);" << endl << endl;
        IntArray c(6, 8);
        for(int i = c.low(); i <= c.high(); i++)
            c[i] = i * 10;
        c.setName("c");
        cout << c << endl;
        csis << c << endl;
        wait();
    }
    
    void test4() {
        cout << "4. Array declared with two identical integers: IntArray d(5, 5);" << endl << endl;
        csis << "4. Array declared with two identical integers: IntArray d(5, 5);" << endl << endl;
        IntArray d(5, 5);
        for(int i = d.low(); i <= d.high(); i++)
            d[i] = i * 10;
        d.setName("d");
        cout << d << endl;
        csis << d << endl;
        wait();
    }
    
    void test5() {
        cout << "5. Array declared with no integers: IntArray z;" << endl << endl;
        csis << "5. Array declared with no integers: IntArray z;" << endl << endl;
        IntArray z;
        for(int i = z.low(); i <= z.high(); i++)
            z[i] = i * 10;
        z.setName("z");
        cout << z << endl;
        csis << z << endl;
        wait();
    }
    
    void test6() {
        cout << "6. Array declared with another object of type IntArray: IntArray c(6, 8);" << endl;
        cout << "                                                        Intarray e(c);"    << endl << endl;
        csis << "6. Array declared with another object of type IntArray: IntArray c(6, 8);" << endl;
        csis << "                                                        Intarray e(c);"    << endl << endl;
        IntArray c(6, 8);
        for(int i = c.low(); i <= c.high(); i++)
            c[i] = i * 10;
        c.setName("c");
        cout << c << endl;
        csis << c << endl;
        IntArray e(c);
        e.setName("e");
        cout << e << endl;    
        csis << e << endl;
        wait();
    }
    
    void test7() {
        cout << "7. Array assigned to another array w/ different indices: IntArray f(1, 4);" << endl;
        cout << "                                                         IntArray g(5, 8);" << endl;
        cout << "                                                         f = g;"            << endl << endl;
        csis << "7. Array assigned to another array w/ different indices: IntArray f(1, 4);" << endl;
        csis << "                                                         IntArray g(5, 8);" << endl;
        csis << "                                                         f = g;"            << endl << endl;
        IntArray f(1, 4);
        for(int i = f.low(); i <= f.high(); i++)
            f[i] = i * 10;
        f.setName("f");
        cout << f << endl;
        csis << f << endl;
        IntArray g(5, 8);
        for(int i = g.low(); i <= g.high(); i++)
            g[i] = i * 10;
        g.setName("g");
        cout << g << endl;
        csis << g << endl;
        wait();
        f = g;
        cout << f << endl;
        cout << g << endl;
        csis << f << endl;
        csis << g << endl;
        wait();
    }
    
    void test8() {
        cout << "8. Multiple array assignment with different indices: IntArray j(3, 6);" << endl;
        cout << "                                                     IntArray k(6, 9);" << endl;
        cout << "                                                     IntArray l(1, 4);" << endl;
        cout << "                                                     j = k = l;"        << endl << endl;
        
        csis << "8. Multiple array assignment with different indices: IntArray j(3, 6);" << endl;
        csis << "                                                     IntArray k(6, 9);" << endl;
        csis << "                                                     IntArray l(1, 4);" << endl;
        csis << "                                                     j = k = l;"        << endl << endl;
        IntArray j(3, 6);
        for(int i = j.low(); i <= j.high(); i++)
            j[i] = i * 10;
        j.setName("j");
        cout << j << endl;
        csis << j << endl;
        IntArray k(6, 9);
        for(int i = k.low(); i <= k.high(); i++)
            k[i] = i * 10;
        k.setName("k");
        cout << k << endl;
        csis << k << endl;
        IntArray l(1, 4);
        for(int i = l.low(); i <= l.high(); i++)
            l[i] = i * 10;
        l.setName("l");
        cout << l << endl;
        csis << l << endl;
        wait();
        j = k = l;
        cout << j << endl;
        cout << k << endl;
        cout << l << endl;
        csis << j << endl;
        csis << k << endl;
        csis << l << endl;
        wait();
    }
    
    void test9() {
        cout << "9. Overloaded equality operator (identical elements): IntArray m(3, 7);"  << endl;
        cout << "                                                      IntArray n(1, 5);"  << endl;
        cout << "                                                      m == n"             << endl << endl;
        csis << "9. Overloaded equality operator (identical elements): IntArray m(3, 7);"  << endl;
        csis << "                                                      IntArray n(1, 5);"  << endl;
        csis << "                                                      m == n"             << endl << endl;
        IntArray m(3, 7);
        for(int i = m.low(); i <= m.high(); i++)
            m[i] = i * 10;
        m.setName("m");
        cout << m << endl;
        csis << m << endl;
        IntArray n(1, 5);
        for(int i = n.low(); i <= n.high(); i++)
            n[i] = i * 10;
        n.setName("n");
        cout << n << endl;
        csis << n << endl;
        wait();
        
        m = n;
        cout << m << endl;
        cout << n << endl;
        cout << "Returns " << (m == n ? "True." : "False.") << endl << endl;
        csis << m << endl;
        csis << n << endl;
        csis << "Returns " << (m == n ? "True." : "False.") << endl << endl;
        wait();
    }
    
    void test10() {
        cout << "10. Overloaded equality operator (different elements): IntArray o(3, 7);" << endl;
        cout << "                                                       IntArray p(1, 5);" << endl;
        cout << "                                                       o == p"            << endl << endl;
        csis << "10. Overloaded equality operator (different elements): IntArray o(3, 7);" << endl;
        csis << "                                                       IntArray p(1, 5);" << endl;
        csis << "                                                       o == p"            << endl << endl;
        IntArray o(3, 7);
        for(int i = o.low(); i <= o.high(); i++)
            o[i] = i * 20;
        o.setName("o");
        cout << o << endl;
        csis << o << endl;
        IntArray p(1, 5);
        for(int i = p.low(); i <= p.high(); i++)
            p[i] = i * 10;
        p.setName("p");
        cout << p << endl;
        cout << "Returns " << (o == p ? "True." : "False.") << endl << endl;
        csis << p << endl;
        csis << "Returns " << (o == p ? "True." : "False.") << endl << endl;
        wait();
    }
    
    void test11() {
        cout << "11. Overloaded equality operator (different size arrays): IntArray q(1, 3);" << endl;
        cout << "                                                          IntArray r(1, 4);" << endl;
        cout << "                                                          q == r;"           << endl << endl;
        csis << "11. Overloaded equality operator (different size arrays): IntArray q(1, 3);" << endl;
        csis << "                                                          IntArray r(1, 4);" << endl;
        csis << "                                                          q == r;"           << endl << endl;
        IntArray q(1, 3);
        for(int i = q.low(); i <= q.high(); i++)
            q[i] = i * 10;
        q.setName("q");
        cout << q << endl;
        csis << q << endl;
        IntArray r(1, 4);
        for(int i = r.low(); i <= r.high(); i++)
            r[i] = i * 10;
        r.setName("r");
        cout << r << endl;
        cout << "Returns " << (q == r ? "True." : "False.") << endl << endl;
        csis << r << endl;
        csis << "Returns " << (q == r ? "True." : "False.") << endl << endl;
        wait();
    }
    
    void test12() {
        cout << "12. Overloaded inequality operator (identical elements): IntArray s(3, 7);" << endl;
        cout << "                                                         IntArray t(1, 5);" << endl;
        cout << "                                                         s != t;"           << endl << endl;
        csis << "12. Overloaded inequality operator (identical elements): IntArray s(3, 7);" << endl;
        csis << "                                                         IntArray t(1, 5);" << endl;
        csis << "                                                         s != t;"           << endl << endl;
        IntArray s(3, 7);
        for(int i = s.low(); i <= s.high(); i++)
            s[i] = i * 10;
        s.setName("s");
        cout << s << endl;
        csis << s << endl;
        IntArray t(1, 5);
        for(int i = t.low(); i <= t.high(); i++)
            t[i] = i * 10;
        t.setName("t");
        cout << t << endl;
        csis << t << endl;
        wait();
        s = t;
        cout << s << endl;
        cout << t << endl;
        cout << "Returns " << (s != t ? "True." : "False.") << endl << endl;
        csis << s << endl;
        csis << t << endl;
        csis << "Returns " << (s != t ? "True." : "False.") << endl << endl;
        wait();
    }
    
    void test13() {
        cout << "13. Overloaded inequality operator (different elements): IntArray u(3, 7);" << endl;
        cout << "                                                         IntArray v(1, 5);" << endl;
        cout << "                                                         u != v;"           << endl << endl;
        csis << "13. Overloaded inequality operator (different elements): IntArray u(3, 7);" << endl;
        csis << "                                                         IntArray v(1, 5);" << endl;
        csis << "                                                         u != v;"           << endl << endl;
        IntArray u(3, 7);
        for(int i = u.low(); i <= u.high(); i++)
            u[i] = i * 10;
        u.setName("u");
        cout << u << endl;
        csis << u << endl;
        IntArray v(1, 5);
        for(int i = v.low(); i <= v.high(); i++)
            v[i] = i * 10;
        v.setName("v");
        cout << v << endl;
        cout << "Returns " << (u != v ? "True." : "False.") << endl << endl;
        csis << v << endl;
        csis << "Returns " << (u != v ? "True." : "False.") << endl << endl;
        wait();
    }
    
    void test14() {
        cout << "14. Overloaded inequality operator (different size arrays): IntArray w(1, 3);" << endl;
        cout << "                                           IntArray x(1, 4);" << endl;
        cout << "                                           w != x;"           << endl << endl;
        csis << "14. Overloaded inequality operator (different size arrays): IntArray w(1, 3);" << endl;
        csis << "                                           IntArray x(1, 4);" << endl;
        csis << "                                           w != x;"           << endl << endl;
        IntArray w(1, 3);
        for(int i = w.low(); i <= w.high(); i++)
            w[i] = i * 10;
        w.setName("w");
        cout << w << endl;
        csis << w << endl;
        IntArray x(1, 4);
        for(int i = x.low(); i <= x.high(); i++)
            x[i] = i * 10;
        x.setName("x");
        cout << x << endl;
        cout << "Returns " << (w != x ? "True." : "False.") << endl << endl;
        csis << x << endl;
        csis << "Returns " << (w != x ? "True." : "False.") << endl << endl;
        wait();
    }
    
    void test15() {
        cout << "15. Sum of two arrays assigned to third array: IntArray a(1, 5);"   << endl;
        cout << "                                               IntArray b(4, 8);"   << endl;
        cout << "                                               IntArray c = a + b;" << endl << endl;
        csis << "15. Sum of two arrays assigned to third array: IntArray a(1, 5);"   << endl;
        csis << "                                               IntArray b(4, 8);"   << endl;
        csis << "                                               IntArray c = a + b;" << endl << endl;
        IntArray a(1, 5);
        for(int i = a.low(); i <= a.high(); i++)
            a[i] = i * 10;
        a.setName("a");
        cout << a << endl;
        csis << a << endl;
        IntArray b(4, 8);
        for(int i = b.low(); i <= b.high(); i++)
            b[i] = i * 10;
        b.setName("b");
        cout << b << endl;
        csis << b << endl;
        wait();
        IntArray c = a + b;
        cout << a + b << endl;
        c.setName("c");
        cout << c << endl;
        csis << c << endl;
        wait();
    }
    
    void test16() {
        cout << "16. Sum of two arrays assigned to first array: IntArray d(10, 13);" << endl;
        cout << "                                               IntArray e(30, 33);" << endl;
        cout << "                                               d += e;"             << endl << endl;
        csis << "16. Sum of two arrays assigned to first array: IntArray d(10, 13);" << endl;
        csis << "                                               IntArray e(30, 33);" << endl;
        csis << "                                               d += e;"             << endl << endl;
        IntArray d(10, 13);
        for(int i = d.low(); i <= d.high(); i++)
            d[i] = i * 10;
        d.setName("d");
        cout << d << endl;
        csis << d << endl;
        IntArray e(30, 33);
        for(int i = e.low(); i <= e.high(); i++)
        e[i] = i * 10;
        e.setName("e");
        cout << e << endl;
        csis << e << endl;
        d += e;
        cout << d << endl;
        csis << d << endl;
        wait();
    }
    
    void test17() {
        cout << "17. Array declared with illegal array bounds: IntArray f(5, 2);" << endl << endl;
        csis << "17. Array declared with illegal array bounds: IntArray f(5, 2);" << endl << endl;
        IntArray f(5, 2);
        for(int i = f.low(); i <= f.high(); i++)
            f[i] = i * 10;
        f.setName("f");
        cout << f << endl;
        csis << f << endl;
        wait();
    }
    
    void test18() {
        cout << "18. Array with index out of range: IntArray g(10);"    << endl;
        cout << "                                   g[10] = 1;"         << endl << endl;
        csis << "18. Array with index out of range: IntArray g(10);"    << endl;
        csis << "                                   g[10] = 1;"         << endl << endl;
        IntArray g(10);
        for(int i = g.low(); i <= g.high(); i++)
            g[i] = i * 10;
        g.setName("g");
        cout << g << endl;
        csis << g << endl;
        g[10] = 1;
        wait();
    }
    
    void test19() {
        cout << "19. Arrays with length mismatch: IntArray m(1, 4);" << endl;
        cout << "                                 IntArray n(2, 4);" << endl;
        cout << "                                 m = n;"            << endl << endl;
        csis << "19. Arrays with length mismatch: IntArray m(1, 4);" << endl;
        csis << "                                 IntArray n(2, 4);" << endl;
        csis << "                                 m = n;"            << endl << endl;
        IntArray m(1, 4);
        for(int i = m.low(); i <= m.high(); i++)
            m[i] = i * 10;
        m.setName("m");
        cout << m << endl;
        csis << m << endl;
        IntArray n(2, 4);
        for(int i = n.low(); i <= n.high(); i++)
            n[i] = i * 10;
        n.setName("n");
        cout << n << endl;
        csis << n << endl;
        wait();
        m = n;
        cout << m << endl;
        cout << n << endl;
        csis << m << endl;
        csis << n << endl;
        wait();
    }
    
    void test20() {
        cout << "20. Array subscript operator: IntArray o(7, 8);" << endl;
        cout << "                              o[7] = 25;"        << endl;
        cout << "                              o[8] = o[7];"      << endl << endl;
        csis << "20. Array subscript operator: IntArray o(7, 8);" << endl;
        csis << "                              o[7] = 25;"        << endl;
        csis << "                              o[8] = o[7];"      << endl << endl;
        IntArray o(7, 8);
        for(int i = o.low(); i <= o.high(); i++)
            o[i] = i * 10;
        o.setName("o");
        cout << o << endl;
        csis << o << endl;
        o[7] = 25;
        o[8] = o[7];
        cout << o << endl;
        csis << o << endl;
        wait();
    }
    
    void wait() {
        char buf;
        
        cout << "Press any key to continue." << endl;
        cin.get(buf);
    }
    Code:
    // iadrv.h
    
    #ifndef _IADRV_H
    #define _IADRV_H
    
    #include "intarray.h"
    
    int main();
    void test1();
    void test2();
    void test3();
    void test4();
    void test5();
    void test6();
    void test7();
    void test8();
    void test9();
    void test10();
    void test11();
    void test12();
    void test13();
    void test14();
    void test15();
    void test16();
    void test17();
    void test18();
    void test19();
    void test20();
    void wait();
    
    #endif
    Last edited by ryanmcclure4; 10-27-2012 at 03:55 PM.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I did not look over all your code, but this is wrong (in operator =):

    for (int i = 0; i <= len; i++)

    Remember that the bounds of an array goes to [0, size - 1].
    Also, regarding references and const functions:

    Passing by reference allows a function to modify the variable that is passed in. It is also more efficient because the object you pass in isn't copied. So the general rule is: whenever you want the function to be able to modify the variable that is passed in OR if it is a big object (general rule: if it's a class, or a struct, use a reference).
    Whenever you pass by reference you should consider if the function should be able to modify the passed in variable or not. If not, then make it a const reference. This will give you a compile error if you accidentially modify it. Better safe than sorry.
    Regarding const functions... whenever you have a member function, you should ask yourself: should this function be able to modify member variables or not? If not, make it const. Example: operator + should not modify the member variables (because it returns a new object with the new values). Speaking of which, you should make the operator + a non-member.
    Last edited by Elysia; 10-27-2012 at 04:08 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by ryanmcclure4 View Post
    Whiteflags - This is an assignment for my class, and the point of the program is to allow the user to create an array with any indices that they would like (-3, 9) etc...which are obviously illegal. So the class creates an object that has an array which appears to use these indices like (-3, 9), but actually uses (0, 12) to store the numbers.


    There is a driver program that does a series of tests whether or not I overloaded the operators correctly (which was the point of this assignment). One of the requirements was that when overloading the assignment operator, we were to make it so that it would keep the "fake" indices of the object's array but copy the values inside the array. So the assignment operator is only changing one part of the class.
    That really doesn't address my problems with the class. By all means, complete your assignment the way the teacher would like; I'm not telling you how to pass. In normal class design, the assignment operator has its semantics almost set in stone, so changing it raises many red flags for me. Assignment is supposed to copy the entire object so that you have two of the exact same thing.

    If an array class needs to take ownership of another array, say a fixed length C array, normally this is done in a member function, not with an operator. I don't know what your teacher is saying, but operators are not always preferable, and generally you want their purpose to stay conventional and obvious. See the example:
    Code:
    int foo[10] = {1,1,2,2,3,3,4,4,5,5};
    IntArray bar (-3, 7); // index 0 through 9 with the range (-3) through 6
    bar.assign(foo);
    See that? It's quite clear that bar just wants to take ownership of foo.
    As you can see I didn't change much about the overloaded assignment operator because since I changed it to pass by const-reference it started working.
    The only problem with it now is that, in the driver program, it assigns three objects to each other (j = k = l) which all have arrays of the same size.
    Ok well I maintain my advice, for the most part. Even discounting my misgivings about the design, you need to modify the current object (pointed to by this, if that wasn't clear before) to get anywhere. Your code does not modify the current object in any way. All of the changes you want are made to temp, not this. Temp is destroyed by the time operator = returns, so that doesn't help matters.

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Elysia View Post
    Is there a reason you do not use std::vector instead of pointers for dynamic arrays?
    And that is no fun!
    Code:
     typedef tuple<vector<int>, string> IntArray;

  15. #15
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by ryanmcclure4 View Post
    iMalc - I read up on passing by const-reference and from what I understand the reason for doing this is so that the compiler doesn't need to make a copy of the object in order to use it in the function (saving space), while at the same time it cannot alter the object? So I should be doing this whenever a function is passing an object of the class type? Or do I only need to do use it when it is also returning the class type? I hope this makes sense...
    Yeah, you nailed it!
    You can use a const reference when returning a class type, or you can use a regular reference. There is not quite consensus over that. I don't even tend to do that consistently myself.

    iMalc - I did not use bool because the requirement for that operator was to return a non zero value if equal, and a zero if not equal.
    Okay, that just means that you're probably being taught by someone who's more of a C programmer than a C++ programmer. This is unfortunately somewhat common. At long as you know that in the real world we use bool for true/false stuff, then that's fine.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. assignment operator overloading problem
    By auralius in forum C++ Programming
    Replies: 3
    Last Post: 05-19-2011, 02:33 AM
  2. Overloading Assignment Operator, this pointer
    By cuo741 in forum C++ Programming
    Replies: 11
    Last Post: 12-09-2010, 09:12 AM
  3. Copy Constructors and Assignment Operator overloading.
    By leeor_net in forum C++ Programming
    Replies: 1
    Last Post: 11-09-2009, 10:26 PM
  4. Assignment operator overloading
    By hsgw in forum C++ Programming
    Replies: 1
    Last Post: 01-20-2007, 06:44 PM
  5. overloading the assignment operator
    By Unregistered36 in forum C++ Programming
    Replies: 1
    Last Post: 11-30-2001, 06:51 AM