Как правильно переопределить "отсутствие неконстантной ссылки на временный объект"

У меня есть класс Foo, Foo имеет несколько неконстантных методов. Я в порядке с вызовом неконстантных методов на временной Foo объект; Меня интересует только то, что методы на самом деле возвращают, чем то, что они делают с Foo сам объект

Первый вопрос: означает ли это само по себе, что класс Foo не продуман?

Второй вопрос: если я хочу продолжить Foo как есть, но я все еще хочу быть в состоянии пройти Foo объекты, ссылающиеся на функции, которые будут вызывать неконстантные методы для него, что будет лучшим способом сделать это?

Вот к чему я пришел:

// The function that performs work on a Foo object.
int TakeFoo (Foo& FooBar) { ... }

// An overload just to accept temporary Foo objects.
int TakeFoo (Foo&& FooBar)
{
    // Delegate
    return TakeFoo(FooBar);
}

Альтернативный подход просто делает это:

int TakeFoo (const Foo& FooBar)
{
    Foo& MyFooBar = const_cast<Foo&>(FooBar);
    // Do work on MyFooBar
}

Но у этого подхода есть проблема, заключающаяся в том, что вы можете использовать const-cast для удаления const на объекте, который фактически был объявлен как const, что поставило бы меня в неопределенную область поведения.

Редактировать:

Примеры кода, использующие TakeFoo:

Foo GimmeFoo() { ... }

cout << TakeFoo(GimmeFoo()) << endl;

Foo ConstructedFoo(...);

cout << TakeFoo(ConstructedFoo) << endl;

// Continue to use ConstructedFoo

1 ответ

Ответьте на свой второй вопрос:

Если ваша функция TakeFoo предназначена для вызова неконстантных членов Foo, используйте

int TakeFoo (Foo& FooBar);

Если вы уверены, что TakeFoo принимает только значение в качестве аргумента, используйте

int TakeFoo (Foo&& FooBar);

Если вы хотите внести некоторые изменения в Foo, чтобы вычислить int возвращаемое значение затем использовать

int TakeFoo (const Foo& FooBar)
{
    Foo FooBar MyFooBar = FooBar;
    // do something with MyFooBar and return int
}

Или же

int TakeFoo (Foo FooBar);

Ответьте на свой первый вопрос:

int TakeFoo (FooBar) не должен изменять FooBar для того, чтобы вычислить int результат. Лучший дизайн будет

Foo transform_foo(Foo const& foo);
int compute_result(Foo const& foo);
int TakeFoo(Foo const& FooBar)
{
    return compute_result( transform_foo(FooBar) );
}
Другие вопросы по тегам