1

So I'm trying to build a template class for a study project about group theory and logic. I have the class:

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
template <class T>
class CSet
{
private:
    T* arr;
    int size;
protected:

public:
    /*Constructors & Destructor*/
    CSet(int s = 0, T* a = NULL); //Default constructor
    CSet(const CSet<T> & obj_input); //Copy constructor
    ~CSet() { delete[] arr; } //Destructor

    /*Operators Overloading*/
    const CSet<T>& operator=(const CSet<T>& obj_input); // = overloading
    const CSet<T>& operator+=(const T& val_input); // += overloading
    const CSet<T>& operator-=(const T& val_input); // -= overloading

    /*Logic Operators Overloading*/
    const CSet<T>& operator|(const CSet<T>& obj_input);
    const CSet<T>& operator&(const CSet<T>& obj_input);
    const CSet<T>& operator-(const CSet<T>& obj_input);
    bool operator==(const CSet<T>& obj_input);
    bool operator!=(const T& val_input);
    bool operator>(const CSet<T>& obj_input);
    const CSet<T>& operator^(const CSet<T>& obj_input);

    //void DifWrite(const CSet<T>& obj_input); //does - and outputs to file

    friend ostream& operator<<(ostream& op, const CSet<T>& input) {
        for (int i = 0; i < input.size; i++)
        {
            op << input.arr[i] << " ";
        }
        return op;
    }
};

and I'm trying to make the | operator to simulate OR logic function. This means that if I make A={1,2,3} and B={3,4,5} then A|B={1,2,3,4,5} which is a new object. However I can't decipher how to allocate memory for the new object and return it. The function I currently have is changing 'this' instead of returning a new object:

template <class T>
const CSet<T>& CSet<T>::operator|(const CSet<T>& obj_input) {
    if (!arr)   
    {
        *this = obj_input;
        return *this;
    }
    else if (!obj_input.arr)
    {
        return *this;
    }
    else
    {
        for (int i = 0; i < size; i++)
        {
            temp += this->arr[i];
        }
        for (int i = 0; i < obj_input.size; i++)
        {
            temp += obj_input.arr[i];
        }
        *this = temp;
    }
    return *this;
}
1
  • 3
    You are doing it wrong: Your operators are binary operators which should return a CSet<T>. The mutating binary operators are @=, which should return CSet<T>&. Commented Jun 3, 2015 at 18:02

1 Answer 1

1

You don't want to return a constant reference to an object you are creating in the function. What you should do is create a object in the function and then return it by value. To do that your code would be:

template <class T>
CSet<T> CSet<T>::operator|(const CSet<T>& obj_input) const
{
    CSet<T> temp;
    temp.size = *this.size + obj_input.size;
    temp.arr = new T[temp.size];
    int i = 0;
    for (; i < *this.size; i++)
        temp.arr[i] = *this.arr[i];
    for (; i - *this.size < obj_input.size; i++)
        temp.arr[i] = *this.arr[i];
    return temp;
}

If you instead use a std::vector instead of raw arrays your function would become:

template <class T>
CSet<T> CSet<T>::operator|(const CSet<T>& obj_input) const
{
    CSet<T> temp;
    temp.arr.insert(temp.arr.end(), *this.arr.begin(), *this.arr.end());
    temp.arr.insert(temp.arr.end(), obj_input.arr.begin(), obj_input.arr.end())
    return temp;
}
Sign up to request clarification or add additional context in comments.

3 Comments

You miss the union-set logic, but idea is here. BTW, operator may be const
So can I use a const or not on the return value? and we are not allowed to use std::vector.
@adam if you are returning by value there is no reason to make the return constant. You can make the function constant thought.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.