0

Related to this question that I asked yesterday.

I'm building my own vector class to learn a little more about C++, and I'm having some difficulty implementing an overloaded operator+ that I can use to add vectors. Here's what my class looks like so far:

template<typename T>
class vector;

template<typename T>
vector<T> operator+(const vector<T>&, const vector<T>&); 

template<typename T>
class vector
{
private:
    T* pointer_;
    unsigned long size_;
public:
    // Constructors and destructors.
    vector();
    template<typename A> vector(const A&);
    template<typename A> vector(const A&, const T&);
    vector(const vector<T>&);
    ~vector();

    // Methods.
    unsigned long size();
    T* begin();
    T* end();
    vector<T>& push_back(const T&); 

    // Operators.
    T operator[](unsigned long);
    vector<T>& operator=(const vector<T>&);
    friend vector<T> operator+<>(const vector<T>&, const vector<T>&);
};

template<typename T>
vector<T> operator+(const vector<T>& lhs, const vector<T>& rhs)
{
    vector<T> result(lhs.size_);
    for (unsigned long i = 0; i != result.size_; i++)
    {
        result.pointer_[i] = lhs.pointer_[i] + rhs.pointer_[i];
    }
    return result;
}

The constructor vector(const A& size, const T& value) operates as expected, returning a vector with size elements initialized to value. operator= appears to be working, as well. When I try something like this, however, my program doesn't perform as expected:

#include <iostream>
#include "vector.h"

int main()
{
    vector<int> test(5, 2); // Create a vector with five elements initialized to 2.
    vector<int> test2(5, 3); // Create a vector with five elements initialized to 3.
    std::cout << test.size() // Prints 5, as expected.
    std::cout << test2.size() // Prints 5, as expected.
    vector<int> try_result = test + test2; 
    std::cout << try_result.size() // Prints 0--why?
}

My question: if operator+ returns a copy of result (and not by reference, a problem that originally existed in my code), why does it appear that try_result still does not point to the proper location in the heap?

EDIT: Adding the constructor code (I've tested this, and it seems to work, but maybe for the wrong reasons):

template<typename T> template<typename A>
vector<T>::vector(const A& size)
{
    this->pointer_ = new T[size];
    this->size_ = size;
}

template<typename T> template<typename A>
vector<T>::vector(const A& size, const T& initial_value)
{
    this->pointer_ = new T[size];
    this->size_ = size;
    for (unsigned long i = 0; i != this->size_; i++)
    {
        pointer_[i] = initial_value;
    }
}

EDIT2: Adding the copy constructor.

template<typename T>
vector<T>::vector(const vector<T>& replicate_vector)
{
    delete[] this->pointer_;
    this->pointer_ = new T[replicate_vector.size_];
    this->size_ = replicate_vector.size_;
    for (unsigned long i = 0; i != this->size_; i++)
    {
        this->pointer_[i] = replicate_vector.pointer_[i];
    }
}
Community
  • 1
  • 1
crcvd
  • 1,465
  • 1
  • 12
  • 23
  • What is `vector result(lhs.size_);` calling ? – quantdev Aug 19 '14 at 23:37
  • Please show the constructor code. – Andrew Lazarus Aug 19 '14 at 23:37
  • Apologies for the oversight. I've added the constructor code for `vector(const A&)` and `vector(const A&, const T&)`. – crcvd Aug 19 '14 at 23:39
  • 1
    Could you give us a [minimal complete example](http://www.sscce.org/)? It would save a lot of work. – Beta Aug 19 '14 at 23:56
  • What does the copy constructor look like? The one that takes `const vector&` – Igor Tandetnik Aug 19 '14 at 23:57
  • 1
    That's not the copy constructor. That's the assignment operator. It's not used in your code, so there's not much point showing it. You have `vector(const vector&);` declared - how is it defined? – Igor Tandetnik Aug 20 '14 at 00:05
  • @IgorTandetnik Apologies for the confusion on my end. It hadn't even occurred to me that the copy constructor could be the issue: after making sure I free dynamically allocated memory there, however, the issue appears to resolve itself. I've updated my code above to include the corrected version of my copy constructor. Is the copy constructor used to handle the return of the `result` value from the `operator+` operator? – crcvd Aug 20 '14 at 00:13
  • `delete[] this->pointer_` in your copy constructor is UB; you haven't initialized `pointer_` yet so you're trying to delete a random pointer. – cdhowie Aug 20 '14 at 00:24
  • @cdhowie So I must initialize first (something like `T* temporary_pointer_ = new T[replicate_vector.size_]`, populate, and *then* `this->pointer_[i] = temporary_pointer_`? Not very familiar with what the copy constructor actually does (lots of learning to do, still)--is it creating an entirely new object? – crcvd Aug 20 '14 at 00:26
  • @Corcovado Yes, it's creating a new object from another object. So primitives of `this` are uninitialized (objects with a no-arg constructor will be initialized automatically). The task of the copy constructor is to make the state of `this` match (but not necessarily be bound to) the state of the argument. So you would want to copy all of the elements of the other object into a new allocation on `this`. – cdhowie Aug 20 '14 at 14:51

0 Answers0