2009-02-09 100 views
1

我不确定我是否缺少一些基本的东西。但我无法理解为什么编译器生成错误此代码:带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:“回归”:无法从“常量类A *”转换为“类A *'转换失去了限定符

+0

你能提供的编译器错误A.实例太? – 2009-02-09 13:28:04

回答

13

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

在你的类B中,由于你没有返回指向成员的指针,你返回它的一个副本(并且成员碰巧是一个指针),所以你没有承诺。

+0

是的,现在就去吧。现在看起来很简单。 – Naveen 2009-02-09 13:35:36

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

但下位产生编译错误(海合会4)

testfile.cpp:37: error: invalid conversion from ‘const A*’ to ‘A*’

因为你的常量获取函数是由非const指针返回到它提供非const接取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; 
} 
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 ::得到()现在返回一个const指针A.

0

成员函数标记const不能返回到一个私有变量非const引用或指针。如果编译器允许这样做,则班级以外的任何人都可以修改该私有变量,并且该函数上的const限定符将失去意义。

0

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

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

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

MyClass::get() constvalue具有类型const int。当你解除引用时,你会得到const int *。这种类型不能安全地(隐含地)流向int *。要更正您的问题,请get()返回const int *

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

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

const A* C::get() const 
{ 
    return &m_a; 
} 
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 
{ 
}; 

这样,你不必做一个“获取”返回