【问题标题】:Compiler Error with const functionconst 函数的编译器错误
【发布时间】:2009-02-09 13:25:46
【问题描述】:

我不确定我是否缺少一些基本的东西。但我无法理解为什么编译器会为此代码生成错误:

class A
{
};

class B
{
public:
    B();
    A* get() const;

private:
    A* m_p;
};

B::B()
{
    m_p = new A;
}

A* B::get() const
{
    //This is compiling fine
    return m_p;
}

class C
{
public:
    A* get() const;
private:
    A m_a;
};

A* C::get() const
{
   //Compiler generates an error for this. Why? 
    return &m_a;
}

编辑:编译器错误是:error C2440: 'return' : cannot convert from 'const class A *' to 'class A *' Conversion lost qualifiers

【问题讨论】:

  • 能否也提供编译器错误?

标签: c++ constants


【解决方案1】:

函数签名中的const 告诉编译器对象的成员可能不会被修改。然而,你返回一个指向成员的非const 指针,从而允许违反该承诺。

在您的B 类中,您没有做出任何承诺,因为您没有返回指向成员的指针,而是返回了它的副本(并且该成员恰好是一个指针)。

【讨论】:

  • 是的..现在知道了。现在看起来很简单。
【解决方案2】:

这是因为您从 const 函数返回一个指向成员的非 const 指针。

第一部分有效,因为您要返回成员指针的副本,因此这不会违反 get 函数的常量:

class B
{
public:
    B();
    A* get() const;

private:
    A* m_p;
};

A* B::get() const
{
    //This is compiling fine
    return m_p;
}

但下一位会产生编译错误(在 gcc 4 上)

testfile.cpp:37: 错误:从‘const A*’到‘A*’的无效转换

因为您的 const get 函数通过返回指向 m_a 的非常量指针来提供对 m_a 的非常量访问。

class C
{
public:
    A* get() const;
private:
    A m_a;
};

A* C::get() const
{
   //Compiler generates an error for this. Why?
    return &m_a;
}

【讨论】:

    【解决方案3】:

    因为返回的指针不是 const。改成这样:

    class C
    {
    public:
        const A* get() const;
    private:
        A m_a;
    };
    
    const A* C::get() const
    {
        //Compiler generates an error for this. Why? 
        return &m_a;
    }
    

    请注意,C::get() 现在返回一个指向 A 的 const 指针。

    【讨论】:

      【解决方案4】:

      标记为const 的成员函数不能返回非常量引用或指向私有变量的指针。如果编译器允许这样做,您类之外的任何人都可以修改所述私有变量,并且函数上的const 限定符将失去意义。

      【讨论】:

        【解决方案5】:

        这个问题可以用一个更简单的例子来说明:

        class MyClass {
        public:
            int *get() const;
        private:
            int value;
        };
        
        int *MyClass::get() const {
            return &value;
        }
        

        MyClass::get() const 中,value 的类型为const int。当你取消引用它时,你会得到const int *。该类型不能安全(隐式)转换为int *。要纠正您的问题,请让get() 返回const int *

        【讨论】:

          【解决方案6】:
          A* C::get() const
          {
             //Compiler generates an error for this. Why? 
              return &m_a;
          }
          

          因为 get() 是一个 const 函数,编译器将它引用的所有成员变量都视为 const。当你获取这样一个成员的地址时,你会得到一个指向 const 的指针。但是您的函数正在返回一个非常量指针。您需要将代码更改为

          const A* C::get() const
          {
              return &m_a;
          }
          

          【讨论】:

            【解决方案7】:

            基本上就是在前面加一个const,

            const A* C::get() const
            {
               //Compiler generates an error for this. Why? 
                return &m_a;
            }
            

            那么如果你想访问它,基本上就是这样做:

            C something;
            
            const A* a = something.get();
            

            但是,对我来说,您的程序毫无意义。

            IMO,这样做最有意义:

            class A{
            };
            
            class C : public A
            {
            };
            

            这样您就不必创建返回 A 实例的“get”。

            【讨论】:

              猜你喜欢
              • 2018-03-16
              • 1970-01-01
              • 1970-01-01
              • 2017-07-04
              • 1970-01-01
              • 2012-03-14
              • 1970-01-01
              • 1970-01-01
              • 2020-09-23
              相关资源
              最近更新 更多