У меня есть метод, который принимает ссылку объекта как const, этот метод ничего не меняет, а константа указывает, что дело в том, что этот метод также вызывает другой метод, который находится внутри класса и является недействительным, не принимает никаких аргументов и также является виртуальным, что означает, что класс, который расширяет базовый класс, может переопределить метод, но он также должен быть const. Например:const-correctness in void methods и лямбда 'трюк'
#include <iostream>
class Boz
{
public:
virtual void introduce() const = 0;
};
class Foo
{
public:
virtual void callable() const
{
// ...
}
void caller(const Boz& object) const
{
callable();
object.introduce();
}
};
class Bar : public Boz
{
public:
void introduce() const
{
std::cout << "Hi." << std::endl;
}
};
class Biz : public Foo
{
public:
void callable() const
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};
int main(void)
{
Biz biz;
biz.caller(Bar());
return 0;
}
Выход будет:
I'm being called before the introduce.
Hi.
Как вы можете видеть callable
сусло быть константной для того, чтобы называться. Если изменить и сделать это:
class Biz : public Foo
{
public:
void callable()
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};
Он будет собирать не ошибки выбрасывается, но вызываемый метод не будет называться, но виртуальная, как это определенно как константы. Это совершенно очевидно.
Сложная часть здесь:
class Foo
{
public:
virtual void callable()
{
// ...
}
void caller(const Boz& object) const
{
auto trick = [&]() { callable(); };
trick();
object.introduce();
}
};
class Biz : public Foo
{
public:
void callable()
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};
Он работает и метод callable
называется. Нет ошибок, таких как passing 'const ...' as 'this' argument
.
Что я пытаюсь сделать, это позвонить callable
без необходимости быть константой, и причина проста: метод ничего не меняет, у него нет доступа к объекту, который начинает передаваться как аргумент на методе caller
, то мы предполагаем, что ему не нужно быть const
, но компилятор также выдает ошибку. Реальная проблема заключается в том, что callable
является виртуальным, и классы могут расширять базовый класс, реализовывать свои собственные callable
и пытаться вызвать другие методы, но не могут, если это не const
.
Что я хочу, это в значительной степени то, что я должен знать, как я могу вызвать виртуальный метод без необходимости быть константой (причина в том, что я предпочитаю, чтобы пользователи, которые расширили класс и переопределили callable
метод только для звонков const
методов, и это не то, что я хочу) и, конечно, понять, что происходит с лямбдой и почему это работает.
Ну, вы можете просто передать неконстантный 'Boz &' to 'caller', если вы специально не хотите передавать ему значения ... – wakjah
Объявив аргумент как const, вы обещаете вызывающему, что вы не измените состояние аргумента. Как вы можете уважать это обещание, если затем передать аргумент неизвестному методу, который также не дает того же обещания? –
Лямбда-трюк не похож на что-то, что должно работать, поскольку оно эффективно отбрасывает 'const' на' this'. 'clang' не принимает этот код, но' g ++ 'делает. Вам нужно 'const_cast' сделать что-то вроде этого или, возможно, улучшить идею, перепроектировать ваш код, чтобы вам не нужно было отбрасывать' const'. – zch