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

StackOverflow https://stackoverflow.com//questions/22076269

Вопрос

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

Пример (также на идеон):

#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-возвращающая функция shape если какая-то другая функция изменяет геометрию, скажем, раскрасьте их по их площади, для чего потребуется доступ к форме геометрии:

// 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];

(Я привел слегка упрощенный некомпилируемый пример по адресу идеон.)

Я понимаю (в какой-то степени), почему это происходит:g это не так const и, следовательно, неконстантная функция shape(), которая является protectec, предположительно должна быть вызвана - но это, очевидно, не удается.

Так что я предполагаю, что мой ВОПРОС является:Есть ли способ получить какой-то "откат" к const-функции, если неконстантная функция недоступна?

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top