C++ 从非常量对象调用 const 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/407100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling a const function from a non-const object
提问by Chris
I need to call a const function from a non-const object. See example
我需要从非常量对象调用 const 函数。查看示例
struct IProcess {
virtual bool doSomeWork() const = 0L;
};
class Foo : public IProcess {
virtual bool doSomeWork() const {
...
}
};
class Bar
{
public:
const IProcess& getProcess() const {return ...;}
IProcess& getProcess() {return ...;}
void doOtherWork {
getProcess().doSomeWork();
}
};
Calling
打电话
getProcess().doSomeWork();
will always results in a call to
总是会导致调用
IProcess& getProcess()
Is there another way to call
有没有其他的调用方式
const IProcess& getProcess() const
from a non constant member function? I have so far used
来自非常量成员函数?我到目前为止使用过
const_cast<const Bar*>(this)->getProcess().doSomeWork();
which does the trick but seems overly complicated.
这可以解决问题,但似乎过于复杂。
Edit: I should mention that code is being refactored and eventually only one function will remain.
编辑:我应该提到代码正在重构,最终只会保留一个功能。
const IProcess& getProcess() const
However, currently there is a side effect and the const call may return a different instance of IProcess some of the time.
但是,目前存在副作用,并且 const 调用有时可能会返回 IProcess 的不同实例。
Please keep on topic.
请继续主题。
采纳答案by MSN
Avoid the cast: assign this to a const Bar *
or whatever and use that to call getProcess()
.
避免强制转换:将其分配给 aconst Bar *
或其他任何东西,然后使用它来调用getProcess()
.
There are some pedantic reasons to do that, but it also makes it more obvious what you are doing without forcing the compiler to do something potentially unsafe. Granted, you may never hit those cases, but you might as well write something that doesn't use a cast in this case.
这样做有一些迂腐的理由,但这也使您在做的事情变得更加明显,而不会强迫编译器做一些可能不安全的事情。当然,您可能永远不会遇到这些情况,但在这种情况下,您不妨编写一些不使用强制转换的内容。
回答by mfazekas
const_cast
is for casting awayconstness!
const_cast
是为了摆脱恒常!
You're casting from non-const to const which is safe, so use static_cast
:
您正在从非常量转换为安全的常量,因此请使用static_cast
:
static_cast<const Bar*>(this)->getProcess().doSomeWork();
I mean techincally speaking you can cast in constness with const_cast
, but it's not a pragmatic use of the operator. The purpose of new style casts (versus the old c-style cast), is to communicate the intent of the cast. const_cast
is a code smell, and it's use should be reviewed at least. static_cast
on the other hand is safe. But it's a matter of C++ style.
我的意思是从技术上讲,您可以使用 进行常量转换const_cast
,但这不是运算符的实用用法。新样式转换(相对于旧的 c 样式转换)的目的是传达转换的意图。const_cast
是一种代码异味,至少应该它的使用。static_cast
另一方面是安全的。但这是 C++ 风格的问题。
Or you can create a new (private) const method, and call that from doOtherWork
:
或者您可以创建一个新的(私有)const 方法,并从doOtherWork
以下位置调用它:
void doSomeWorkOnProcess() const { getProcess().doSomeWork(); }
Using a const temporary is also an option (answer by "MSN"):
使用 const 临时也是一种选择(由“MSN”回答):
const Bar* _this = this;
_this->getProcess().doSomeWork();
回答by CB Bailey
If getProcess()
and getProcess() const
are not returning a reference to the same object (but differently qualified) then it would indicate a poor design of class Bar
. Overloading on the const
ness of the function is not a good way to distinguish functions with different behaviours.
如果getProcess()
并且getProcess() const
没有返回对同一对象的引用(但限定不同),则表明class Bar
. 重载const
函数的性质并不是区分具有不同行为的函数的好方法。
If they are returning a reference to the same object then:
如果它们返回对同一对象的引用,则:
const_cast<const Bar*>(this)->getProcess().doSomeWork();
and
和
getProcess().doSomeWork();
call exactly the same doSomeWork()
function so there is no need to use the const_cast
.
调用完全相同的doSomeWork()
函数,因此无需使用const_cast
.
回答by j_random_hacker
If the cast is too ugly for you, you could instead add a method to Bar
that simply returns a const reference to *this
:
如果强制转换对您来说太难看,您可以改为添加一个方法,Bar
该方法只返回对 的 const 引用*this
:
Bar const& as_const() const {
return *this; // Compiler adds "const" without needing static_cast<>
}
You can then call anyconst
method in Bar
just by prepending as_const().
, e.g.:
然后,您可以通过添加来调用任何const
方法,例如:Bar
as_const().
as_const().getProcess().doSomeWork();
回答by Alexander Drichel
define a template
定义模板
template< class T >
const T & addConst ( T & t )
{
return t;
}
and call
并打电话
addConst( getProcess() ).doSomeWork();
回答by Judge Maygarden
You don't have to do any casting trickery if the function is not overloaded. Calling a const method of a non-const object is fine. It's calling a non-const method from a const object that is forbidden. If the methods are overridden with a const and non-const function, then casting the object to const will do the trick:
如果函数没有重载,你就不必做任何转换技巧。调用非常量对象的 const 方法没问题。它正在从禁止的 const 对象调用非常量方法。如果这些方法被 const 和非常量函数覆盖,那么将对象转换为 const 就可以了:
const_cast<const IProcess&> (getProcess()).doSomeWork();
EDIT: I didn't read the whole question. Yes, you need to const_cast the thispointer or make the doOtherWorkfunction const to call const IProcess& getProcess() const.
编辑:我没有阅读整个问题。是的,您需要 const_cast this指针或使doOtherWork函数 const 调用const IProcess& getProcess() const。
The point remains that you don't need a const object to call doSomeWork. Since that is the goal, do you need the const method called?
关键仍然是您不需要 const 对象来调用doSomeWork。既然这是目标,您是否需要调用 const 方法?
Another option would be to rename the over-ridden functions. This would be a really good idea if the two function actually have different behavior/side-effects. Otherwise, the effect of the function call would not be obvious.
另一种选择是重命名被覆盖的函数。如果这两个函数实际上具有不同的行为/副作用,这将是一个非常好的主意。否则,函数调用的效果不会很明显。
回答by Judge Maygarden
Well, can you declare
那么,你能不能声明
void doOtherWork const ()
?
?
That would do it.
这样就可以了。
回答by Roddy
I assume you want DoOtherWork to call one of your two getprocess calls depending on on whether it's called from a const object or not.
我假设您希望 DoOtherWork 调用您的两个 getprocess 调用之一,具体取决于它是否从 const 对象调用。
The best I can suggest is this:
我能建议的最好的是:
class Bar
{
public:
const IProcess& getProcess() const {return ...;}
IProcess& getProcess() {return ...;}
void doOtherWork { // should use getProcess()
getProcess().doSomeWork();
}
void doOtherWork const {
getProcess().doSomeWork(); // should use getProcess() const
}
};
Even if that works, this looks like a bad smell to me. I'd be very wary of the class behaviour changing radically according to the constness of an object.
即使这有效,这对我来说也是一种难闻的气味。我会非常警惕根据对象的常量性从根本上改变的类行为。
回答by Chris
Posted by monjardin
Another option would be to rename the over-ridden functions. This would be a really good idea if the two function actually have different behavior/side-effects. Otherwise, the effect of the function call would not be obvious.
monjardin 发表
另一种选择是重命名被覆盖的函数。如果这两个函数实际上具有不同的行为/副作用,这将是一个非常好的主意。否则,函数调用的效果不会很明显。
IProcess& is accessed in other code mostly through a property
IProcess& 在其他代码中主要通过属性访问
__declspec(property(get=getProcess)) IProcess& Process;
so renaming was not an option. Majority of the time constness of the calling function matches getProcess() so there was no issue.
所以重命名不是一种选择。大多数情况下,调用函数的常量性与 getProcess() 匹配,因此没有问题。
回答by JaredPar
I think the const_cast method is your best option. This is just a limitation of the const framework in C++. I think the only way you could avoid the casting is to define a method which returns const IProcess instance regardless. For instance.
我认为 const_cast 方法是你最好的选择。这只是 C++ 中 const 框架的一个限制。我认为避免强制转换的唯一方法是定义一个无论如何都返回 const IProcess 实例的方法。例如。
const IProcess* getProcessConst() const { return ... }
...
getProcessConst().doSomeWork();