我不确定我是否遗漏了一些基本的东西。但我无法理解为什么编译器会为此代码生成错误:
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 *'转换失去限定符
答案 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”。