перегрузка функций на основе констант через открытый / защищенный доступ

(Я верю), я знаю о перегрузке функций, основанных на константности: если момент — констант, вызывается метод констант, в противном случае — неконстантный.

Пример (также на 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-функции, если неконстантная функция недоступна?

0

Решение

Есть ли способ получить какое-то «отступление» к const-функции, если неконстантная функция недоступна?

Нет; Разрешение перегрузки происходит перед проверкой доступа.

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

1

Другие решения

Вы можете использовать const_cast разрешить вызывать константную версию как:

int main()
{
S s2;
const_cast<const S&>(s2).print(); // prints "const method"return 0;
};

Но было бы лучше / проще переименовать один из методов.

0

По вопросам рекламы [email protected]