(Я верю), я знаю о перегрузке функций, основанных на константности: если момент — констант, вызывается метод констант, в противном случае — неконстантный.
Пример (также на ideone):
#include <iostream>
struct S
{
void print() const { std::cout << "const method" <<std::endl };
void print() { std::cout << "non-const method" <<std::endl };
};
int main()
{
S const s1;
s1.print(); // prints "const method"S s2;
s2.print(); // prints "non-const method"return 0;
};
Я пытался / пытался использовать это в своем коде, но столкнулся с некоторыми проблемами, когда const
перегруженные методы не имеют одинаковую категорию доступа. Это может быть плохой стиль, но вот пример, который отражает идею возврата ссылок, чтобы избежать копирования и использования const
чтобы ограничить непреднамеренные изменения:
struct Color;
struct Shape
{
double area;
};
class Geometry
{
public:
// everybody can alter the color of the geometry, so
// they get a mutable reference
Color& color() { return m_color; };
// not everybody can alter the shape of the Geometry, so
// they get a constant reference to the shape.
Shape const& shape() const { return m_shape; };
protected:
// derived classes can alter the shape, so they get
// access to the mutable reference to alter the shape.
Shape & shape() { return m_shape; };
private:
Shape m_shape;
Color m_color;
};
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я хочу, чтобы компилятор принимал публику, const
— возвращение функции формы, если какая-то другая функция смешивается с геометрией, скажем, раскрасьте их по площади, для чего потребуется доступ к форме геометрии:
// this one fails
void colorByArea() {
for( Geometry g : geometryList )
{ g.color() = colorMap[g.shape().area]; }
}
// this one is a clunky workaround
void colorByArea() {
for( Geometry g : geometryList )
{
Geometry const& g_const = g;
g.color() = colorMap[g_const.shape().area];
}
}
Это (или что-то подобное) завершается ошибкой со следующей довольно понятной ошибкой:
‘Shape& Geometry::shape()’ is protected
Shape & shape() { return m_shape; };
^ error: within this context
g.color() = colorMap[g.shape().area];
(Я поднял немного упрощенный пример некомпиляции в ideone.)
Я понимаю (до некоторой степени), почему это происходит:g
не является const
и, следовательно, якобы должен вызываться неконстантный shape (), который является protectec, но это явно не помогает.
Так что я думаю, мой ВОПРОС является:
Есть ли способ получить какое-то «отступление» к const-функции, если неконстантная функция недоступна?
Есть ли способ получить какое-то «отступление» к const-функции, если неконстантная функция недоступна?
Нет; Разрешение перегрузки происходит перед проверкой доступа.
Это не просто плохой стиль; это плохой дизайн. Общественная функция получения концептуально разные из защищенной функции, которая позволяет коду со знанием внутренних органов изменять внутреннее состояние объекта. В общем случае две функции не обязательно должны иметь связанные типы возврата. Поэтому они не должны иметь одно и то же имя.
Вы можете использовать const_cast
разрешить вызывать константную версию как:
int main()
{
S s2;
const_cast<const S&>(s2).print(); // prints "const method"return 0;
};
Но было бы лучше / проще переименовать один из методов.