const函数的编译器错误

时间:2009-02-09 13:25:46

标签: c++ const

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

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;
}

编辑:编译错误是:错误C2440:'return':无法从'const class A *'转换为'class A *'转换失去限定符

7 个答案:

答案 0 :(得分:13)

函数签名中的

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

在你的班级B中,由于你没有返回指向某个成员的指针而你没有做出任何承诺,你会返回它的副本(并且该成员恰好是指针)。

答案 1 :(得分:3)

这是因为你从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函数通过返回一个非const指针来为m_a提供非const访问。

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

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

答案 2 :(得分:1)

因为返回的指针不是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的。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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 *

答案 5 :(得分:0)

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;
}

答案 6 :(得分:0)

基本上只需在前面添加一个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”。