在C ++下我经常遇到错误。 假设我有以下类:
class ClassData
{
public:
ClassData() { a=-1; }
public:
int a;
};
class MyClass
{
public:
MyClass() { m_classData = 0; }
MyClass(ClassData* classData) { m_classData = new ClassData(*classData); m_classData->a=1; }
inline bool getClassData(ClassData* classData) {
if (m_classData) { classData = m_classData; return true; }
else return false;
}
private:
ClassData* m_classData;
};
现在主要是我运行这个测试代码:
ClassData cdata;
MyClass* m_myClass = new MyClass(&cdata);
int value = 0;
ClassData classData;
if (m_myClass->getClassData(&classData))
value = classData.a;
如果代码运行,value
等于-1(而不是1)。
第一个问题:为什么我无法在ClassData
中引用MyClass
?虽然我正在考虑拥有ClassData
m_myClass
的{{1}}对象(如果它是公开的那样做m_myClass->m_classData
),实际上我正在呼叫成员{{1在本地a
对象上。
我在想,原因是我无法更改本地变量地址,但如果我将代码更改为:
ClassData
我的程序崩溃了。
第二个问题:管理这种情况的正确方法是什么?问题是在程序主函数中还是在定义ClassData* classData=0;
if (m_myClass->getClassData(classData))
value = classData->a;
的方式中为错误提供了空间?
答案 0 :(得分:1)
下面:
bool getClassData(ClassData* classData) {
if (m_classData) { classData = m_classData; return true; }
else return false;
}
请注意classData
是本地变量。它在函数终止时死掉,所以函数除了报告m_classData
是否为空之外什么都不做。
所以在第一种情况下:
ClassData classData; // <-- classData.a is -1
if (m_myClass->getClassData(&classData))
value = classData.a; // <-- classData.a is still -1
在第二种情况下:
ClassData* classData=0; // classData is null
if (m_myClass->getClassData(classData))
value = classData->a; // classData is still null
取消引用空指针,即未定义行为。你很幸运,它只是崩溃。
正确(但仍然不安全)的方法是这样的:
bool getClassData(ClassData* classData) {
if (m_classData!=0 && classData!=0)
{ classData->a = m_classData->a; return true; }
else return false;
}
我说“仍然不安全”,因为此函数无法真正验证这些指针指向有效的数据结构。为了避免这种危险,你必须避免使用如此多的指针,并查看引用。
答案 1 :(得分:0)
使用值而不是指针可以简化操作,还可以消除内存泄漏。见live example
#include <iostream>
class ClassData
{
public:
ClassData() { a=-1; }
public:
int a;
};
class MyClass
{
public:
MyClass() { }
explicit
MyClass(ClassData const& classData) {
m_classData = classData;
m_classData.a=1;
}
ClassData const& getClassData() const {
return m_classData;
}
private:
ClassData m_classData;
};
int main()
{
ClassData classData;
MyClass myClass( classData );
classData = myClass.getClassData();
int value = classData.a;
std::cout << value;
}