0

The goal I set to myself is to overload operator+ (adding class objects). It turns out that this sum can be just interpreted as the sum of two vectors. But when it comes to the method operator+, I find it difficult to return the object. I've read similar topics and even try to apply some sugestions but with no success, unfortunatelly. I enclose some of my code.

template<class Y>
class myVect {
public:
    myVect(int n = 1);                          
    ~myVect();
    myVect(const myVect& a);                    

    myVect& operator= (const myVect&);
    myVect& operator+ (const myVect&);

    void display(const myVect& a);      

private:
    int size;
    Y* data;
    template<class U> friend class myClass;     
}; 

template<class Y>                               // constructor      
myVect<Y>::myVect(int n) {
    size = n;
    data = new Y[size];
    cout << endl << "Pass the elements" << " " << size << "\n";
    for (int i = 0; i < size; i++) {
        cin >> *(data + i);
    }
}

template <class Y>                             // deconstructor                 
myVect<Y> :: ~myVect() {
    delete[] data;
}



template<class Y>                               // copy constructor
myVect<Y> ::myVect(const myVect & a) {
    size = a.size;
    data = new Y[size];                         

    for (int i = 0; i < size; i++) {
        *(data + i) = *(a.data + i);            
    }
}

template<class Y>                              //ASSIGMENT OPERATOR                                                 
myVect<Y> & myVect<Y> :: operator= (const myVect<Y> & a) {
    if (this != &a) {                                                   
        delete[] data;                                                  
        size = a.size;                                                  
        data = new Y[size];
        for (int i = 0; i < size; i++) {
            *(data + i) = *(a.data + i);
        }
    }
    return *this;
}

The method operator+ is a follows:

template<class Y>
myVect<Y>& myVect<Y> ::operator+ (const myVect<Y>& a) {
    if (this->size != a.size) {
    cout << endl << "not able to perform that operation - wrong dimensions" << endl;
    }
    else {
        myVect<Y> newObj(this->size);
        for (int i = 0; i < this->size; i++) {
            *(newObj.data + i) = *(this->data + i) + *(a.data + i);
        }
    }
    return newObj;                                                      
}       

The error I get is 'newObj': identifier not found. I believe it's due to deconstructor. I tried to put the class myVect into a new class (encapsulate it) and contruct the return method but it didn't change antything - the type of the error is still the same. Do you know how to solve this problem?

Anyway, if it is the destructor fault, does that mean that newObj is deleted before its return?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
zorro47
  • 221
  • 1
  • 11
  • 12
    `operator+` should return a new instance not a reference – 463035818_is_not_an_ai Jun 28 '19 at 14:43
  • operator+ (along with most other binary operators) should normally be a free (non-member) function taking two reference parameters and returning a value, not a reference. –  Jun 28 '19 at 14:44
  • 2
    While returning by reference is a problem here (it's not being used correctly, and it generally can't be used for `operator+`) it is not the cause of the problem you are asking about. The question you are asking about is strictly a scope issue. – François Andrieux Jun 28 '19 at 14:44
  • To expand on some of the other comments, in general, you should return by reference for operators that modify state, and return by value for operators that are "pure". – 0x5453 Jun 28 '19 at 14:46
  • 3
    1) `newObj` is defined in the `else` block, hence you can't "see" it outside of it. 2) Returning reference to a local variable can lead to undefined behavior, upon using the returned reference: [C++ Returning reference to local variable](https://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable). – Algirdas Preidžius Jun 28 '19 at 14:46
  • 1
    FrançoisAndrieux is right, I was a bit too fast in closing as dupe, nevertheless you should give this a read: https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading – 463035818_is_not_an_ai Jun 28 '19 at 14:47
  • @moooeeeep the q was already closed as dupe of that and then reopened, if you read carefully, the specific problem OP is asking about wont be fixed by returning a value – 463035818_is_not_an_ai Jun 28 '19 at 14:49
  • 1
    Function returns reference to a local variable is wrong practice since that variable will not be exist when the function call is done, and then the reference referencing nothing. – muaz Jun 28 '19 at 16:01
  • Thank you for all your comments. I've been learning c++ for a month and sometimes quite simple things make me helpless. It seems like I must study scope of variables. – zorro47 Jun 28 '19 at 17:31

2 Answers2

5

The problem can be reduced to this:

int foo()
{
    if (true)  // In reality, some meaningful condition
    {
       int x = 4;
    }

    return x;
}

The variable is scoped to the if block. It doesn't exist outside of it.

You'll have to move its declaration out of the conditional, and do whatever else is required to make that work… or return from inside the condition, and do something else (throw an exception?) otherwise.

For example, given the above demonstration:

int foo()
{
    int x = 0; // Or some other value

    if (true)  // In reality, some meaningful condition
    {
       x = 4;
    }

    return x;
}

or:

int foo()
{
    if (true)  // In reality, some meaningful condition
    {
       int x = 4;
       return x;
    }

    throw std::runtime_error("For some reason I have no value to give you!");
}

Your next problem will be that you are trying to return a local variable by reference. You cannot do that. Return it by value instead, which is anyway idiomatic for what you're doing.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

You've declared your object inside of a block, so it won't exist in the outside scope. This would normally free you up to reuse variable names across different branches; try making a newObj inside the if part of the statement and watch it not throw an error, for example.

David
  • 10,458
  • 1
  • 28
  • 40
  • I put ``newObj`` before ``if`` and now it's ok. – zorro47 Jun 28 '19 at 15:02
  • I'm still studying up on return by reference, value, and pointer, so while I've covered the scope issue, you should see @LightnessRacesinOrbit 's answer for more detail on the possible errors this method could have – David Jun 28 '19 at 15:17