Есть вот такой код:
#include <iostream>
#include <memory>
using namespace std;
template<class T> class copy_on_write_ptr {
private:
shared_ptr<T> ptr;
void detach() {
T* p = ptr.get();
if (p && !ptr.unique())
ptr = make_shared<T>(*p);
}
public:
copy_on_write_ptr(const copy_on_write_ptr<T>&) = default;
copy_on_write_ptr(T* p)
: ptr(p) { }
const T* operator->() const {
return ptr.operator->();
}
T* operator->() {
detach();
return ptr.operator->();
}
};
struct self {
const self* ptr() const {
return this;
}
self() = default;
self(const self&) = default;
};
int main()
{
copy_on_write_ptr<self> p1(new self());
cout << p1->ptr() << endl;
const copy_on_write_ptr<self> p2(p1);
cout << p2->ptr() << endl;
cout << p1->ptr() << endl;
}
Выполняю и получаю в консоли
0x4c5a10
0x4c5a10
0x4c5ba0
Почему в последнем случае получается другой адрес? Почему выполнился detach
? Я же вызываю константный метод объекта. Ну как так-то?
Что можно сделать чтобы вызов константных методов не приводил к вызову detach
? Понятно, что можно объявить p1
константным и detach
вызван не будет. Но задача поставлена так, чтобы вызов константных методов класса self
не приводил к вызову detach
даже если экземпляр класса copy_on_write_ptr
сам по себе неконстантный.
По умолчанию для non-const lvalue выбирается оверлоад без const-квалификации.
Что можно сделать чтобы вызов константных методов не приводил к вызову detach?
Ну, собственно, вызвать их как-то, заставив компилятор считать p1 константой:
template<class T> decltype(auto) invokePtr(T const &p) {
return p->ptr();
}
template<class T> T const &constCast(T const &p) { return p; }
invokePtr(p1);
constCast(p1)->ptr();
const_cast<copy_on_write_ptr<self> const &>(p1)->ptr();
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Привет! Это мой не первый пост по поводу парсера, но все жеСобственно, проблема такова: есть список(вектор) токенов(указателей на них) и на его...