C++の関数呼び出しと下付きおよびメンバーアクセス演算子のリロードの詳細

3557 ワード

関数呼び出しカッコで呼び出される関数呼び出し演算子は、二元演算子です.構文

primary-expression ( expression-list )

注記このコンテキストではprimary-expressionが最初のオペランドです.そしてexpression-list(パラメータの可能な空のリスト)は2番目のオペランドです.関数呼び出し演算子は、多数のパラメータを必要とする操作に使用されます.これは、expression-listが単一オペランドではなくリストであるためです.関数呼び出し演算子は非静的メンバー関数でなければなりません.関数呼び出し演算子は、リロード時に関数の呼び出し方法を変更しません.逆に、演算子はクラスのタイプのオブジェクトを指定するときに、演算子を解釈する方法を変更します.たとえば、次のコードは通常意味がありません.

Point pt;
pt( 3, 2 );

ただし、適切なリロード関数呼び出し演算子がある場合、この構文は、x座標を3単位オフセットし、y座標を2単位オフセットするために使用できます.次のコードには、次の定義が表示されます.

// function_call.cpp
class Point
{
public:
  Point() { _x = _y = 0; }
  Point &operator()( int dx, int dy )
    { _x += dx; _y += dy; return *this; }
private:
  int _x, _y;
};

int main()
{
  Point pt;
  pt( 3, 2 );
}


関数呼び出し演算子は、関数の名前ではなくオブジェクトの名前に適していることに注意してください.関数自体ではなく、関数を指すポインタを使用して、関数呼び出し演算子を再ロードすることもできます.

typedef void(*ptf)();
void func()
{
}
struct S
{
  operator ptf()
  {
   return func;
  }
};

int main()
{
  S s;
  s();//operates as s.operator ptf()()
}


関数呼び出し演算子などの下付き文字の演算子は、二元演算子として扱われます.下付き文字の演算子は、単一のパラメータを使用する非静的メンバー関数である必要があります.このパラメータは任意のタイプであり、必要な配列の下付き文字を指定できます.次の例では、境界チェックを実行するintタイプのベクトルを作成する方法を示します.

// subscripting.cpp
// compile with: /EHsc
#include 

using namespace std;
class IntVector {
public:
  IntVector( int cElements );
  ~IntVector() { delete [] _iElements; }
  int& operator[]( int nSubscript );
private:
  int *_iElements;
  int _iUpperBound;
};

// Construct an IntVector.
IntVector::IntVector( int cElements ) {
  _iElements = new int[cElements];
  _iUpperBound = cElements;
}

// Subscript operator for IntVector.
int& IntVector::operator[]( int nSubscript ) {
  static int iErr = -1;

  if( nSubscript >= 0 && nSubscript < _iUpperBound )
   return _iElements[nSubscript];
  else {
   clog << "Array bounds violation." << endl;
   return iErr;
  }
}

// Test the IntVector class.
int main() {
  IntVector v( 10 );
  int i;

  for( i = 0; i <= 10; ++i )
   v[i] = i;

  v[3] = v[9];

  for ( i = 0; i <= 10; ++i )
   cout << "Element: [" << i << "] = " << v[i] << endl;
}
Array bounds violation.
Element: [0] = 0
Element: [1] = 1
Element: [2] = 2
Element: [3] = 9
Element: [4] = 4
Element: [5] = 5
Element: [6] = 6
Element: [7] = 7
Element: [8] = 8
Element: [9] = 9
Array bounds violation.
Element: [10] = 10


注記iが前のプログラムで10に達した場合、operator[]は境界を超えた下付き文字を使用してエラーメッセージを送信したかどうかを検出します.関数operator[]は参照タイプを返します.これにより、左の値になり、割り当て演算子のいずれかの側で下付き式を使用できます.
メンバー・アクセス・クラス・メンバー・アクセスは、メンバー・アクセス演算子(C>)を再ロードすることによって制御できます.この演算子はこの使用法の一元演算子とみなされ、リロード演算子関数はクラスメンバー関数でなければなりません.したがって、このような関数の宣言は、構文です.

class-type *operator�C>()

注記class-typeは、この演算子が属するクラスの名前です.メンバー・アクセス演算子関数は、非静的メンバー関数でなければなりません.この演算子(通常はポインタの参照解除演算子とともに使用されます)は、参照の解除または使用のカウント前にポインタを検証するためのスマートポインタです.再ロードできません.メンバーは演算子にアクセスします.