-2
myclass myclass::operator+(const myclass& array2) const
{
    myclass newArray(array, size);
    return newArray;
}

when I try to return array2, it works. But newArray, it terminates program. Why ?

edit:

I'm not much worked about OOP. Therefore I cant know what I should give here to be enough. And ,please write detailed a bit.

The program have assignment operator but here I dont use it:

int main(){
   int test[35]={0 to 35} //filled using for loop
   myclass a1(test, 10); // constructor works for filling a1 by first 10 element of test
   myclass a2(test, 20);
   a1+a2;
}
Murat
  • 1
  • 3
  • 4
    Yes and so it should. But you have a bug in another part of your code. – juanchopanza Mar 19 '17 at 17:01
  • 1
    Yes, the code you've shown is fine, although the preferred way of implementing operator+ is through operator+=. That's pretty much only `return *this += rhs;`. – DeiDei Mar 19 '17 at 17:05
  • 3
    Ensure that `myclass` observes [The Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – user4581301 Mar 19 '17 at 17:05
  • This cannot be answered without a [mcve] – Angew is no longer proud of SO Mar 19 '17 at 17:09
  • @DeiDei Implementing `+` as `+=` has the side-effect of altering its left operand, which violates how we expect addition to work, and also cannot be used on `const` objects. if your type has an efficient move constructor, returning a temporary, like here, is nearly as fast. If you only want to implement `+=` because it’s more efficient than `+`, just don’t implement `+`? – Davislor Mar 19 '17 at 18:34
  • the codes under `operator+` will be changed, it will add `array2` to `this`. I need `+` operator, not `+=`. – Murat Mar 19 '17 at 19:13
  • Other solutions: return a *programmatic constructor*, or copy a temporary that has an efficient move constructor using `std::move`. – Davislor Mar 19 '17 at 19:23
  • I will try to return a constructor, but actually I want to know the reason that why above code does not work. I searched much before writing here, but cant understand, since I am new :( – Murat Mar 19 '17 at 20:09
  • It’s impossible to tell why your code doesn’t work without a MCVE. The bug is somewhere else in your code. – Davislor Mar 19 '17 at 22:03

1 Answers1

1

It’s impossible to tell what’s wrong without a Minimal, Complete, Verifiable Example. In this case, that means the relevant parts of your class definition and a main() function.

In case this helps, here’s an example of three different ways to write an efficient operator+ and an operator-. They use some fairly advanced techniques. The implementation of operator+ relies on the compiler to use the provided move constructor and optimize away any redundant copies. The implementation of operator- calls a programmatic constructor that uses a dummy parameter for the unary version, then a function object for the binary version.

#include <array>
#include <cassert>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <new>
#include <utility>
#include <vector>

using std::cout;
using std::endl;
using std::size_t;

// A four-element vector, implemented internally with std::vector.
class vec4i {
  private:
    static constexpr size_t size = 4U;

   /* Object holding the vector data. The compiler knows how to destroy it,
    * so we do not need to write our own destructor.
    */
    std::vector<int> data;
   /* Empty class used as a dummy parameter to tell the compiler that we are
    * calling the programmatic constructor, not the copy constructor.
    */
    struct op_opposite {};

    // Programmatic constructor used by unary operator-:
    vec4i( const vec4i& v, const op_opposite& /* unused */ )
    : vec4i()
    {
      for (size_t i = 0; i < size; ++i)
        data[i] = -v[i];
    }

   /* The type of a generic function object implementing a binary function. */
    using binary_fun = std::function<int(const int, const int)>;

   /* We're going to demonstrate a different approach for operator-, a
    * programmatic constructor using an arbitrary binary function object from
    * <functional>.
    */
    vec4i( const vec4i& u, const vec4i& v, const binary_fun f )
    : vec4i()
    {
      for ( size_t i = 0; i < size; ++i )
        data[i] = f(u[i], v[i]);
    }

  public:
    // Default constructor initializes matrix to zeroes:
    vec4i() : data(size) {}
    // Constructors that provide values:
    vec4i( const std::vector<int>& v ) : data(v) {}
    vec4i( const int x, const int y, const int z, const int w )
    : data{x,y,z,w}
    {}
    vec4i( const int v[size] )
    : data(size)
    {
      for ( size_t i = 0; i < size; ++i )
        data[i] = v[i];
    }
    // Copy constructor that makes a deep copy:
    vec4i(const vec4i& v) : data(v.data) {}
    // Move constructor that avoids a deep copy:
    vec4i(vec4i&& v) : data(std::move(v.data))
    {}
    // One final example, using STL iterators, since it's a one-liner:
    vec4i(const std::array<int, size>& a) : data(a.begin(), a.end()) {}

   /* Provide an assignment operator from any object that can be used to  
    * construct this type.  Ensure that the class does not assign from its own
    * internal data.
    */
    template<class T> vec4i& operator=(const T& v)
    {
      // Check for self-assignment.
      if ((void*)this != (void*)&v) {
        // Call the destructor, then create a new object in-place.
        this->~vec4i();
        new(this) vec4i(v);
      }

      return *this;
    }
    vec4i operator=(vec4i&& v)
    // A more efficient assignment that moves rather than copies the data:
    {
      if ((void*)this != (void*)&v) {
        data.clear();
        data.swap(v.data); // Could also write: data = std::move(v.data);
      }

      return *this;
    }

    // Accessor returning a rvalue:
    int operator[]( const size_t i ) const
    {
      return data[i];
    }
    // Accessor returning a lvalue:
    int& operator[]( const size_t i )
    {
      return data[i];
    }

    // The implementation of operator+ that this example is demonstrating:
    vec4i operator+(const vec4i& v) const
    {
      vec4i temp;

      for ( size_t i = 0; i < size; ++i )
        temp[i] = data[i] + v[i];

     /* Since we provided a move constructor and move assignment above, the
      * compiler should be able to optimize away this copy!
      */
      return temp;
    }

    // Returns a vector with the sign of each elemeent flipped:
    vec4i operator-(void) const
    {
      // The dummy second parameter selects the programmatic constructor.
      return vec4i( *this, op_opposite() );
    }

    // Now we use the constructor above to construct the return value:
    vec4i operator-(const vec4i& v) const
    {
      // Function object wrapping a-b, initialized once:
      static const binary_fun subtract = std::minus<int>();
      // Create the returned temporary object in place.
      return vec4i( *this, v, subtract );
    }
};

std::ostream& operator<<( std::ostream& os, const vec4i& v )
// Serialize our vector.
{
  return os <<
    '<' << v[0] << ',' << v[1] << ',' << v[2] << ',' << v[3] << '>';
}

int main(void)
{
  const vec4i u = {0,0,0,1}, v = {1,0,0,0};

  // Output: "<1,0,0,1>"
  cout << u+v << endl;
  // Output: "<-1,0,0,1>"
  cout << u-v << endl;
  // output: "<-1,0,0,1>"
  cout << -(v-u) << endl;

  return EXIT_SUCCESS;
}
Davislor
  • 14,674
  • 2
  • 34
  • 49