【问题标题】:Can regular instances of a class call constant functions?类的常规实例可以调用常量函数吗?
【发布时间】:2015-11-14 12:05:51
【问题描述】:

我知道常量对象或函数只能对常量成员进行操作,但反过来可以吗?

【问题讨论】:

  • 你为什么没试过? (答案是“是的,对象作为const T* this 传递给调用)
  • 编译器可以将对象隐式转换为该类型的const&。因此,在似乎使用非 const 对象调用 const 函数的情况下,实际上使用了该对象的隐式 const 强制转换。 (就像您将非 const 对象传递给任何显式采用 const& 的函数一样)
  • @MatsPetersson 因为在 C++ 中,成功编译和执行的东西不足以证明它是有效的,而不是例如未定义的行为。

标签: c++ class constants member


【解决方案1】:

常规(非 const)类成员函数可以调用任何 const 和非 const 类成员函数。

【讨论】:

    【解决方案2】:

    简短的回答是

    这就是 C++ 中 const 函数的美妙之处。您可以根据其const-ness 重载方法:

    class Vector
    {
    public:
       int GetItem();
       int GetItem() const;
    };
    

    const Vector 对象会导致调用 const 方法,但非常量 (Vector) 会导致调用非常量。让编译器确定要调用哪个方法(const 或 non-const)。因此:

    v.GetItem();
    

    可能会调用其中任何一个,具体取决于v 的实际类型。

    为什么 C++ 允许它考虑任何“Get”方法应该是只读函数的情况? 好吧,这不是语言律师的理由,请考虑一下。

    向量 v; v[0] = 10;

    如果vector<> 中的重载运算符被声明为const,它将不允许运算符 ([]) 用于左侧(即作为左值)。 如果只提供了非常量,这将失败:

    void process(const vector<int>& v)
    {
        cout << v[0]; // Must call const op []
    }
    

    但是由于方法可以在const的基础上进行重载,编译器会计算出要调用哪个重载。

    另一方面,C++ 允许 const 转换为非常量,反之亦然(const_cast 和 C 样式转换),您始终可以从(非)常量对象调用其他版本。

    ((Vector*)&cv)->GetItem();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      相关资源
      最近更新 更多