2009-03-30 2 views
-1

Используйте случай:Избегайте нулевые проверки указателей в C++

class B { 

    int b; 
    public: 
     int getB() { 
       return b; 
     } 
}; 

class A { 
     B *b; 
    public: 
      int getB() { 
       if (b) {      //How can I avoid the null check for b here 
        return b->getB(); 
       } 
      } 
    } 
+0

Зачем вам нужно избегать проверок нулевого указателя? –

+0

Да, было бы хорошо знать, чего вы пытаетесь достичь ... оптимизация? Чистый код? – timday

+1

не является нулевой проверкой в ​​неправильном месте? getB() должен возвращать B или ... null (что еще он мог бы вернуть?) –

ответ

2

У вас есть много вариантов. Вот 5.

Решение 1: Передайте ссылку B в A вместо указателя.

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

class A 
{ 
    B &b; 
public: 
    A (B& b_) : b(b_) 
    { 
    } 

    int getB() 
    { 
    return b.getB(); 
    } 
}; 

Решение 2: Не жертвуйте дизайн отношения ваших классов с этим, но это может быть применимо.

Имейте класс A, полученный из B. Тогда вы можете просто вызвать getB().


Решение 3: Возможно, вы не должны использовать указатель на всех и просто сделать Б а член А.

class A 
{ 
    B b; 

public: 
    int getB() 
    { 
    return b.getB(); 
    } 
}; 

Решение 4: Утверждай сразу к избежать последующих проверок

class A 
{ 
    B *b; 
public: 
    A (B* pb) : b(pb) 
    { 
    assert(pb != NULL); 
    } 

    int getB() 
    { 
    return b->getB(); 
    } 
}; 

Решение 5: Есть по умолчанию B в том, что вы используете

class A 
{ 
    B *pb; 
    B defaultB; 
public: 
    A() : pb(&defaultB) 
    { 
    } 

    void setB(B* pb_) 
    { 
    if(pb != NULL) 
     pb = pb_; 
    } 

    int getB() 
    { 
    return pb->getB(); 
    } 
}; 
6

Решение 1: Используйте ссылки, если это возможно.

Решение 2: Просто выполните проверку нулевого указателя и дайте компилятору позаботиться о них. Удаление избыточных проверок нулевого указателя является стандартной оптимизацией в эти дни. Они не улавливают всех, кроме большей части избыточности.

8

Что вы ожидаете, если B равно нулю, а затем в getB()? Если это недействительное состояние для вашей программы, просто утвердите (b! = NULL). Если это действительное состояние, вам нужна проверка.

Некоторые языки поддерживают контракты, поэтому вам не нужно вручную писать контрольный код, но, к сожалению, C++ этого не делает.

0

Как упоминал Брайан Бонди, ссылка является одним из языковых способов сделать это. Единственный другой вариант, который я знаю об оффшорах, чтобы избежать нулевых проверок, - Null Object Pattern. Это, конечно, подразумевает большую работу и контроль над тем, как вы получаете объект B.

0
// case: you expect *b can be 0 
class A { 
    B *b; 
public: 
    int getB() { 
     return b ? b->getB() : getDefaultValue(); 
    } 
} 

// case: there is shouldn't be a chance *b can be 0 
class AA { 
    B *b; 
public: 
    AA(B *bValue): 
     b(bValue) 
    { 
     assert(b); 
    } 

    int getB() { 
     return b->getB(); 
    } 
}; 
Смежные вопросы