web-dev-qa-db-ja.com

C ++で「これ」を渡す方法

C++のthisキーワードと混同していますが、thisを渡して正しいことをしているのかどうかわかりません。これが私が苦労しているコードの一部です:

ClassA::ClassA( ClassB &b) {

    b.doSth(this);
    // trying to call b's routine by passing a pointer to itself, should I use "this"?
}

ClassB::doSth(ClassA * a) {
       //do sth
}
17
cplusplusNewbie

正しく使用しています。 thisポインターは、現在のオブジェクトインスタンスを指します。

_class helper 
{
public:
     void help(worker *pWorker) {
          //TODO do something with pWorker . . .
     }

     void help2(worker& rWorker) {
          //TODO do something with rWorker . . .
     }
};

class worker 
{
public:
     void dowork() {
          //this one takes a worker pointer so we can use the this pointer.
          helper.help(this);

          //to pass by reference, you need to dereference the this pointer.
          helper.help2(*this);
     }
     helper helper;
};
_

また、worker *pW = new worker()を宣言するとします。 pWオブジェクトのメソッド(dowork)の1つを呼び出すと、thisポインターとpWの値がまったく同じであることがわかります(どちらも同じアドレスです)。

(ビルドを確認するためにテストしていませんが、そうすべきだと思います)。

24
cchampion

C++では、thisは、「現在のオブジェクトインスタンスへのポインタ」として定義されているキーワードです。したがって、上記のコードは正しいです。

ClassAClassBの間の継承/構成の関係によっては、thisポインターを使用するよりも、実行していることを実現するためのより良い方法がおそらくあります。

10

あなたがしているように「this」または「* this」を渡すことは完全にOKです。

生涯の危険:

提供した例に関する1つのポイントは、doSthのコンストラクターからClassAを呼び出していることです。 doSthに渡されるオブジェクトは、部分的に構築されたオブジェクトである可能性があります。

class ClassC {
public:
  ClassC ()
  : m_c ()
  {}
  int m_c;
};

class ClassA : public ClassC {
public:
  ClassA (ClassB & b)
  : ClassC ()
  , m_b ( b.doSth (this) )  // ClassC constructed
                            // ClassA members partially init.
  {
    b.doSth (this);         // ClassA members initialized
  }

  // ...
  int m_a;
};

class ClassD : public ClassA {
public:
  ClassD(ClassB & b)
  : ClassA (b)              // Partially init
  , m_d ()
  {
                            // ClassC and ClassA constructed
                            // ClassD members initialized
  }
  int m_d;
};

doSthがまだ初期化されていないメンバーを使用している場合、問題が発生する可能性があります。

void ClassB::doSth (ClassA * a) {
  int i = a->m_c;     // OK m_c is initialized

  int j = a->m_a;     // Not OK, m_a not initialized when called
                      // from member initialization list.

  int k = static_cast<ClassD*> (a).m_d;  // Not OK
}

オブジェクトの動的タイプを使用:

最後に、オブジェクトの動的タイプ(たとえば、仮想呼び出し、dynamic_cast、typeid)を使用すると、部分的に構築されたオブジェクトと完全なオブジェクトで異なる結果が得られます(場合によっては、未定義の動作が発生する可能性があります)。

void ClassB::doSth (ClassA * a) {
  if (ClassD * d = dynamic_cast<ClassD *> (a))
  {
    // Never true when called from ClassA::ClassA
  }
}
6
Richard Corden

この場合、thisを使用すると、呼び出し元クラス(A)へのポインターがb.DoSthに渡されます。あなたはそれを正しくやっているようです。 thisキーワードは常に、それを使用しているクラスインスタンスを指します。

2
red.clover

thisはオブジェクトインスタンスへのポインタなので、実行していることは正しいです。

詳細については、 this をお読みください。

0
empc

thisは、それ自体のオブジェクトへのconstポインターです。 thisポインタは変更できません。

  ClassA::ClassA( ClassB &b) {

        b.doSth(this);
        // here 'this' refers to this object ie the instance of ClassA. 
        // When you pass 'this' to doSth function --> is equivalent to passing 
        // the instance of current object of ClassA.
        //   
    }
0
aJ.