2

代入演算子と加算演算子をオーバーロードする単純なベクトル クラスを作成しました。コードは 2 つのベクトルを加算し、加算の前後にベクトルを出力します。驚くべきことに、デストラクタ ~MyVector() は行 c=a+b の後で呼び出されています。オブジェクトa、b、cのいずれも範囲外にならないため、その理由はわかりません。デストラクタの呼び出しの理由を理解していますか?

#include<iostream>
#include<cstdlib>

using namespace std;

template<typename T>
class MyVector
{
  public:

  MyVector(int s)
  {
    size=s;
    a=new T[s];
  }

  ~MyVector()
  {
    delete[] a;
    size=0;
  };

  void freeVec()
  {
    cout<<"Calling destructor. a[0]= "<<a[0]<<endl;
    if(a!=NULL)
    {
      free(a);
      a=NULL;
    }
  }

  int getSize(void)
  {
    return size;
  }
  void setSize(int ss)
  {
    size=ss;
  }
  T &operator[](int i)
  {
    return a[i];
  }

  MyVector &operator=(MyVector mv)
  {
    if(this==&mv)
      return *this;
    for(int i=0;i<mv.getSize();i++)
      this->a[i]=mv[i];
    this->size=mv.getSize();
    return *this;
  }

  MyVector operator+(MyVector &mv)
  {
    for(int i=0;i<size;i++)
    {
      this->a[i]+=mv[i];
    }
    cout<<endl;
    return *this;
  }

  private:
  int size;
  T *a;
};

int main(void)
{
  MyVector<int> a(3),b(3),c(3);

  a[0]=1;a[1]=2;a[2]=3;
  b[0]=4;b[1]=5;b[2]=6;
  cout<<"initial vector"<<endl;
  for(int i=0;i<3;i++)
    cout<<a[i]<<"  ";
  cout<<endl;
  for(int i=0;i<3;i++)
    cout<<b[i]<<"  ";
  cout<<endl;

  c=a+b;  

  cout<<"final vectors"<<endl;
  for(int i=0;i<3;i++)
    cout<<a[i]<<"  ";
  cout<<endl;
  for(int i=0;i<3;i++)
    cout<<b[i]<<"  ";
  cout<<endl;
  for(int i=0;i<3;i++)
    cout<<c[i]<<"  ";
  cout<<endl;

  cout<<endl;
  return 0;
}
4

3 に答える 3

0

ラインc = a + b;には、実際には 2 つの操作があります。1つ目は追加です。あなたがそれを実装した方法aは、実際には の値だけインクリメントされますb。のコピーがa行に返されreturn *this;ます。このコピーはまだ に割り当てられていませんc。それは無名の一時です。

代入呼び出しでは、このコピーが値渡しされるため、別のコピーが作成されます。ただし、コピーの省略では、2 番目のコピーが最適化されている可能性があると思うので、合計で 1 つのコピーが作成されます。したがって、代入演算子への入力はオブジェクトのコピーです。代入演算子が戻ると、そのオブジェクトは破棄されます。

あなたの質問とはやや直交していますが、演算子を実装した方法には多くの問題があることを指摘したいと思います。まず、+オペレーターは関連付けられているオブジェクトを変更しています。行では、関数の行のためにc = a + b;aが変更さthis->a[i]+=mv[i];れますが、これは意図した効果ではないと思います。

次に、=オペレーターの実装では、行

if(this==&mv)
  return *this;

mv は値で渡され、thisとにかく同じアドレスを持つことはないため、役に立ちません。

于 2013-08-22T20:10:49.273 に答える