zorro47
zorro47

Reputation: 221

Returning an object in c++ by reference

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?

Upvotes: 0

Views: 116

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385385

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.

Upvotes: 5

David
David

Reputation: 10708

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.

Upvotes: 2

Related Questions