Явный конструктор и перегрузка

template<typename T>
class RAII
{
public:

    explicit RAII( T* p = 0 ): p_(p){}

    ~RAII() {delete p_;}

    T& operator*() const { return p_;} 
    T* operator‐>() const{ return p_;}
};

//Usage example:
{
      RAII<std::vector<int>> r(new std::vector<int>());
      std::cout<<r­‐>size()<<std::endl;
} // The std::vector<int> is automatically deallocated

Привет, ребята:)

Мой вопрос: какова цель явного конструктора и перегрузок двух операторов в этом конкретном случае, и как они используются в примере использования?

Заранее спасибо.

1 ответ

Во-первых, есть две ошибки: p_ не объявлено, и возвращение в operator* должно быть return *p_,


Во всяком случае, явным является то, что конструктор не может быть вызван неявно.

Учти это:

class Example {
public:
    int x;
    Example(int x) : x(x) {}
};

function ex(const Example& e) {
    std::cout << e.x;
}

int main() {
    ex(5);
    return 0;
}

Вы ожидаете, что это скомпилировать? Оно делает. И он выводит 5. Причина в том, что Пример построен неявно. В основном ex(5) молча превращается в ex(Example(5)), Пометка конструктора как явного запрещает такое поведение. Если вы добавили явное в конструктор, это будет ошибка времени компиляции.


Что касается перегрузки операторов, то здесь у вас есть базовый "умный" указатель. (Я бы, вероятно, использовал один из стандартных в C++11 или Boost, если вы не можете использовать компилятор, который имеет стандартизированные, кстати.)

Перегрузка оператора позволяет объекту реагировать на объекты определенным образом. В этой ситуации перегрузка оператора позволяет классу притворяться указателем на тот же тип, который он содержит.

RAII<std::vector<int>> r(new std::vector<int>());
std::cout<<r­‐>size()<<std::endl;

r притворяется std::vector<int>* через перегрузку оператора здесь. Что действительно происходит, так это то, что он называется:

(r­.operator->())->size()

operator-> возвращает std::vector<int>*итак второе -> получает доступ к этому и вызывает size() метод.

Другой пример перегрузки операторов, с которой вы, вероятно, знакомы, это std::vector's operator[], operator[] возвращает ссылку на элемент.

Перегрузка оператора, конечно, не всегда используется, чтобы притворяться, что делает уже встроенные вещи. Рассматривать ostream"s operator<<, Вместо оператора побитового сдвига он помещает данные в поток.


Дополнительная информация: стандартные интеллектуальные указатели / улучшенные интеллектуальные указатели / RAII / перегрузка операторов.

Да, и ваш код нарушает очень часто соблюдаемое правило три (или правило пяти в C++11). Таким образом, ваш класс будет дважды удалять указатель, если сделана копия.

RAII<int> p(new int)
RAII<int> q = p;
//when q's destructor runs, bad bad things will happen since p's destructor already deleted the int.
Другие вопросы по тегам