Проверка, если вызывающий и параметр совпадают - PullRequest
0 голосов
/ 30 августа 2011

Например, у меня есть четыре класса, например:

class A;

class B{
protected:
    void check(const A &a); 
};

class C : public A, public B;
class D : public B;

Теперь я хотел бы написать функцию проверки, которая ничего не делает, если вызывающая сторона и параметр одинаковы:

void B::check(const A &a){
   if(*this != a){
      //do something
   }
   else{
      //do nothing
   }
}

Однакоэто не скомпилируется, так как класс B ничего не знает о классе C, который однажды вызовет проверку функции B.Было бы легко привести this в A, но это дало бы ошибку, если бы однажды класс D вызвал бы эту проверку, поскольку она не имеет ничего общего с A. Как тогда это делается?

Править: Я мог бы упомянуть, что классы C и D будут иметь интерфейс для вызова этой проверки, которая недоступна вне этих классов, но она не сделает ничего, кроме просто передачи параметра во внутреннюю функцию

Ответы [ 6 ]

3 голосов
/ 30 августа 2011

Это будет работать, если вы добавите виртуальный деструктор в A:

void B::check(const A &a)
{
    if (dynamic_cast<const B*>(&a) == this)
    {
        std::cout << "same object" << std::endl;
    }
}
2 голосов
/ 30 августа 2011
if(*this != a)

Проверка не имеет смысла, потому что это (класс B) никогда не будет таким же, как тип класса A, потому что оба являются несвязанными классами.

Непонятно, что вы хотите сделать, но если вы хотите, чтобы указатель базового класса указывал на ваш объект производного класса, тогда между ними должна быть связь наследования (is-a).

1 голос
/ 30 августа 2011

Здесь есть только один возможный аварийный люк. Если оба A и B имеют виртуальную функцию, то вы можете dynamic_cast оба this и &a. И согласно 5.2.7 / 7 «Если T -« указатель на cv void », то результатом будет указатель на наиболее производный объект, на который указывает v."

Следовательно, этот код работает:

void B::check(const A &a){
   if(dynamic_cast<void const*>(const_cast<B const>(this) != dynamic_cast<void const*>(&a)) {
      //do something
   } ...

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

0 голосов
/ 30 августа 2011

Это то, что вы ищете - чтобы проверить, являются ли this и a частями одного и того же объекта типа C?

void B::check(A &a)
{
    std::cout << (static_cast<C*>(this) != static_cast<C*>(&a)) << std::endl;
}

int main()
{
    C c;
    D d;
    A& a1 = c;
    A a2;
    boolalpha(std::cout);
    c.check(a1); // false
    c.check(a2); // true
    d.check(a1); // true
}
0 голосов
/ 30 августа 2011

Вы можете сделать что-то вроде этого:

void check(const A &a){
   if((void*)this != (void*)&a){
      //do something
   }
   else{
      //do nothing
   }
}
0 голосов
/ 30 августа 2011

Вы, вероятно, хотите проверить, совпадают ли экземпляры:

void B::check(const A &a){
   if(this != &a){
      //do something
   }
   else{
      //do nothing
   }
}

Сравнение содержимого разных классов не имеет большого смысла для меня.

...