无法将'this'指针从'const Line'转换为'Line&'说明?

时间:2011-07-08 02:29:14

标签: c++ compiler-errors

此方法:

bool Point::Intersects(const Line& line) const {
    return (line.ContainsPoint(*this, false));
}

导致此错误:无法将'this'指针从'const Line'转换为'Line&' 这个改变:

bool Point::Intersects(const Line& line) const {
    return const_cast<Line&>(line).ContainsPoint(*this, false);
}

修复了错误,但似乎不是解决问题的正确方法。为什么原始方法被认为是错误?

如果有帮助,ContainsPoint(const Point& point, bool isInfinite)是非常量的,它调用的所有方法也都是非常量的。

3 个答案:

答案 0 :(得分:62)

从某种意义上说,你实际上是自己提供了答案。

Intersects方法中,参数line被声明为const。这限制了您如何使用此变量。具体来说,您只能在其上调用const方法,并且只能将其传递给期望const线对象的方法。

但是,您指出ContainsPoint未声明为const。所以它不满足上面提到的要求(即不允许在const对象上调用非const方法。这就是原始方法生成错误的原因,它也解释了为什么第二个版本有效,因为限制通过const_cast得到了缓解。

真正的问题在于ContainsPoint的声明(也可能是它所调用的任何方法,因为它们也是非const)。这里似乎存在很大的设计缺陷。由于ContainsPoint的目的是检查Point是否在Line上,因此副作用会出乎意料。因此,没有理由不将其作为const方法。实际上(并且您的示例显示了这一点),Line的用户期望 ContainsPoint成为const方法。因此,真正的解决方案是更改Line类的设计,以便将ContainsPoint之类的方法声明为const,并且只有明确更改实例状态的方法才会保留为非const

答案 1 :(得分:7)

在这种情况下,您在const引用上调用非const方法,这是不允许的。您有两种选择:

  1. 做你做的和const_cast
  2. 使ContainsPoint成为const方法

答案 2 :(得分:2)

问题其实很简单:

你有一个A类,带有非const 方法foo(),你通过引用const来调用非const方法foo()。

const A& a = ...;
a.foo();  // failed

这就是const所针对的:一个const变量意味着,声明它不会被改变。虽然foo()“会改变自己”(因为foo()是一个非const方法,这意味着:“我合法改变里面的东西”),这就是编译器抱怨的原因:你有一个const var(a) ,但你要改变它的内容(通过foo())

解决方法很简单,但你应该知道哪种方法是正确的:

1)如果你确定通过const ref等调用foo()应该是合法的,你应该将它声明为const方法:A :: foo()const {...}

2)如果你知道foo()不适合制作const,你应该考虑

2.1)检查“a”以查看是否更适合制作非const或

2.2)在A中找到另一个完成工作的const方法。

(还有其他一些方法,比如使用mutable或const_cast,但这不是99.9%的时间。所以我这里没有提到)