2009-12-01 2 views
10

Я запутался с ключевым словом this в C++, я не уверен, что если я поступаю правильно, пропустив this. Вот кусок кода, который я борюсь с:как передать «это» в C++

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 
} 
+0

Когда вы «себя» в этом комментарии, вы имеете в виду объект ClassA или объект ClassB? – Stobor

+1

В чем ваш вопрос? Что вы ожидаете и что получаете? – fserb

+0

У вас есть вопрос, или вы просто делились? –

ответ

2

В этом случае с помощью this будет передать указатель на класс вызывающего абонента, который является, в b.DoSth. Кажется, вы делаете все правильно. this ключевое слово всегда указывает на экземпляр класса, из которого вы его используете.

8

В C++ this - это ключевое слово, которое определяется как «указатель на экземпляр текущего объекта». Таким образом, ваш код указан правильно.

В зависимости от соотношения наследования/композиции между ClassA и ClassB, есть, вероятно, более эффективные способы достичь того, что вы делаете, чем с помощью this указателя.

0

this является указателем на экземпляр объекта, поэтому то, что вы делаете, является правильным.

Для получения дополнительной информации прочитайте this.

0

this является указателем константы на свой собственный объект. 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. 
     // 
    } 
14

Вы используете его правильно. Этот указатель указывает на текущий экземпляр объекта.

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(). Если вы вызовете один из методов (dowork) объекта pW, вы заметите, что указатель this и pW имеют то же самое значение (они оба одинакового адреса).

(не проверял, чтобы убедиться, что он строит, но я думаю, что это должно).

5

Это нормально, если вы пройдете «это» или «это», как вы это делаете.

Lifetime Опасность:

Один пункт о примере вы поставка, что вы звоните 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) будет иметь разные результаты на partiall y, а не на полном объекте (и в некоторых случаях вы можете иметь неопределенное поведение).

void ClassB::doSth (ClassA * a) { 
    if (ClassD * d = dynamic_cast<ClassD *> (a)) 
    { 
    // Never true when called from ClassA::ClassA 
    } 
} 
Смежные вопросы