【发布时间】:2014-12-17 23:36:31
【问题描述】:
我有一个方法接受一个对象的引用作为 const,这个方法不会改变方法的任何内容,而 const 表示,问题是这个方法还调用了类中的其他方法,并且是void,不接受任何参数并且也是虚拟的,这意味着扩展基类的类可以覆盖该方法,但它也需要是 const。例如:
#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 必须是 const 才能被调用。如果我改变并这样做:
class Biz : public Foo
{
public:
void callable()
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};
它会编译不会抛出错误,但不会调用可调用方法,而是定义为 const 的虚拟方法。这很明显。
这里最棘手的部分:
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 而不需要是 const 原因很简单:该方法没有改变任何东西,他无权访问开始传递的对象caller 方法上的参数然后我们假设他不需要是 const 但即使这样编译器也会抛出错误。真正的问题是callable 是虚拟的,类可以扩展基类,实现自己的callable 并尝试调用其他方法,但如果不是const 也不能。
我想要的几乎是,知道如何在不需要 const 的情况下调用虚拟方法(原因几乎是,我有点强迫用户扩展类并覆盖 @ 987654334@ 方法只调用 const 方法,这不是我想要的)当然要了解 lambda 会发生什么以及它为什么起作用。
【问题讨论】:
-
好吧,你可以将非 const
Boz&传递给caller,除非你特别想将右值传递给它...... -
通过将参数声明为 const,您向调用者保证您不会更改参数的状态。如果你将参数传递给一个不做出同样承诺的未知方法,你怎么能尊重这个承诺?
-
Lambda 技巧看起来不应该起作用,因为它有效地丢弃了
const上的this。clang不接受此代码,但g++接受。你需要const_cast来做这样的事情,或者,可能更好的主意,重新设计你的代码,这样你就不需要丢弃const。 -
But what is happening with the lambda?一个编译器错误,据我所知。它不应该编译。 -
你不应该使用
const_cast。您应该已经决定是否需要Foo常量。如果您确实希望它保持不变,请将const放在caller和callable上。如果不这样做,请从两者中删除const。我说的是const,它位于右括号和左括号之间。
标签: c++ c++11 lambda theory c++14