c++ - 通过引用传递数据以构建它

标签 c++ pointers pass-by-reference

在 C++ 下,我通常会遇到错误。 假设我有以下类(class):

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)。

第一个问题:为什么我无法在MyClass 中引用ClassData?虽然我想拥有 m_myClassClassData 对象(就像做 m_myClass->m_classData 如果它是公开的),实际上我在本地 ClassData 对象上调用成员 a

我在想原因是我不能改变局部变量地址,但是如果我把代码改成这样:

ClassData* classData=0;
if (m_myClass->getClassData(classData))
    value = classData->a;

我的程序崩溃了。

第二个问题:处理这种情况的正确方法是什么?问题出在程序主函数上还是出在 getClassData 的定义方式上,是否存在错误?

最佳答案

这里:

bool getClassData(ClassData* classData) {
  if (m_classData) { classData = m_classData; return true; }
  else return false;
}

请注意 classData 是一个本地 变量。它在函数终止时死亡,因此该函数除了报告其 m_classData 是否为 null 之外实际上什么都不做。

所以在第一种情况下:

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

我说“仍然不安全”是因为这个函数无法真正验证这些指针是否指向有效的数据结构。为避免这种危险,您必须避免过度使用指针,并查看引用。

关于c++ - 通过引用传递数据以构建它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35134630/

相关文章:

c++ - 我们如何初始化结构?

c++ - Qt 是否有与 Boost 的分配模块等效的东西?

C - 如何通过引用将结构指针数组传递给函数

c - 为什么 TaskSpawn 采用整数而不是 void*?

c++ - CMakeLists 包含子目录中的头文件

c++ - 当我通过删除临时节点来释放内存时,我遇到了读取访问冲突。但只有当我返回虚假陈述时

Java递归按值/引用传递

java - JNI 通过引用传递,这可能吗?

带有 TypeScript : passing parameters by reference 的 Angular 4

c++ - 我在为静态文本设置字体时遇到问题