C++ 通过辅助函数引用传递
C++ passing by reference with helper functions
void BTreeTest::testOneBTreeLeafNode() {
BTreeLeafNode *test = new BTreeLeafNode();
BTreeData *info1 = new BTreeData;
BTreeData *info2 = new BTreeData;
BTreeData *info3 = new BTreeData;
BTreeData *info4 = new BTreeData;
BTreeData *info5 = new BTreeData;
setInfo(&*info1, (char *)"Lester", (char *)"24", (char *)"student", 6, 2, 7);
setInfo(&*info2, (char *)"David", (char *)"20", (char *)"student", 5, 2, 7);
setInfo(&*info3, (char *)"June", (char *)"4", (char *)"toddler", 4, 1, 7);
setInfo(&*info4, (char *)"Lisa", (char *)"18", (char *)"tutor", 4, 2, 5);
setInfo(&*info5, (char *)"Savannah", (char *)"22", (char *)"barista", 8, 2, 7);
correctData(&*info1, (char *)"Lester", (char *)"24", (char *)"student");
correctData(&*info2, (char *)"David", (char *)"20", (char *)"student");
correctData(&*info3, (char *)"June", (char *)"4", (char *)"toddler");
correctData(&*info4, (char *)"Lisa", (char *)"18", (char *)"tutor");
correctData(&*info5, (char *)"Savannah", (char *)"22", (char *)"barista");
delete info1;
delete info2;
delete info3;
delete info4;
delete info5;
delete test;
}
这是我为要构建的程序编写的测试。但是,为了让我有一个更清晰、更具可读性的测试,我需要一个辅助函数。这就是 setInfo 的用途。这是代码:
void setInfo(BTreeData *info, char *name, char *age, char *occupation, int
nameSize, int ageSize, int occSize) {
strncpy(info->name, name, nameSize);
strncpy(info->age, age, ageSize);
strncpy(info->occupation, occupation, occSize);
}
问题是我正在尝试设置信息的值。我正在尝试通过引用传递,以便我可以设置信息。当我检查 xCode 调试器时,它可以正常工作,直到 setInfo 函数结束。但出于某种原因,当我的代码返回 testOneBTreeLeafNode
以继续执行其余代码时,信息中的值会发生变化。它有额外不需要的垃圾,如下图所示。我对通过引用传递的理解很差。谁能赐教一下?
注意大卫的年龄和职业应该是 20 岁和学生。它有 20 和学生,但也有其他不需要的垃圾。为什么会这样?
如果有必要,这里有 BTree 结构:
//
// BTree.hpp
// CS130FinalProject
//
// Created by Lester Dela Cruz on 2/19/16.
// Copyright © 2016 Lester Dela Cruz. All rights reserved.
//
#ifndef BTree_hpp
#define BTree_hpp
#define M (5)
#define L (3)
#include <stdio.h>
struct BTreeData {
char name[20];
char age[3];
char occupation[30];
};
struct BTreeLeafNode {
BTreeData dataItems[L];
};
struct BTreeInternalNode {
char keys[M-1][20];
BTreeLeafNode *branch[M];
};
class BTree {
};
#endif /* BTree_hpp */
这是因为您没有复制终止空字符。
您正在堆上分配 BtreeData
class 的新实例。每个实例的初始副本包含随机二进制垃圾。分配在堆上的 POD 数据未用零初始化。
然后您将使用 strncpy
() 来初始化字段。要将 age
成员初始化为“20”,您要为 ageSize
传递 2,因此 strncpy
() 将复制“2”和“0”,但不会尾随的 \0 应该终止 C 风格的字符串。因此,您的调试器看不到尾随的 0,然后继续打印它找到的任何随机垃圾,因为正如我所说,class 实例从堆中分配并继承了之前在堆中的任何随机数据-分配的内存。
其他一些善意的批评,希望大家注意:
setInfo(&*info1, (char *)"Lester", (char *)"24", (char *)"student", 6, 2, 7);
首先,“&*”完全没有任何作用。这没有任何区别。
其次,不建议显式 (char *)
转换。您必须这样做的原因是因为字符串文字是 const char
s,而您的 setInfo
() 函数将 char *
作为参数。
除了您的 setInfo
() 不需要首先采用 char *
参数。让我们更改 setInfo
() 以将 const char *
作为参数,并摆脱这些丑陋、丑陋的转换。
这看起来像是大型应用程序的一部分,因此您传递显式字符串长度计数可能是有原因的,但没有实际原因。顺其自然,使用 strcpy
() 而不是 strncpy
(),忘记字符数。
更好的是,既然我们在这里谈论 C++
,让我们摆脱所有 char
数组,并用 std::string
替换它们。普通 char
数组是如此...上个世纪。
我们达成协议了吗?
void BTreeTest::testOneBTreeLeafNode() {
BTreeLeafNode *test = new BTreeLeafNode();
BTreeData *info1 = new BTreeData;
BTreeData *info2 = new BTreeData;
BTreeData *info3 = new BTreeData;
BTreeData *info4 = new BTreeData;
BTreeData *info5 = new BTreeData;
setInfo(&*info1, (char *)"Lester", (char *)"24", (char *)"student", 6, 2, 7);
setInfo(&*info2, (char *)"David", (char *)"20", (char *)"student", 5, 2, 7);
setInfo(&*info3, (char *)"June", (char *)"4", (char *)"toddler", 4, 1, 7);
setInfo(&*info4, (char *)"Lisa", (char *)"18", (char *)"tutor", 4, 2, 5);
setInfo(&*info5, (char *)"Savannah", (char *)"22", (char *)"barista", 8, 2, 7);
correctData(&*info1, (char *)"Lester", (char *)"24", (char *)"student");
correctData(&*info2, (char *)"David", (char *)"20", (char *)"student");
correctData(&*info3, (char *)"June", (char *)"4", (char *)"toddler");
correctData(&*info4, (char *)"Lisa", (char *)"18", (char *)"tutor");
correctData(&*info5, (char *)"Savannah", (char *)"22", (char *)"barista");
delete info1;
delete info2;
delete info3;
delete info4;
delete info5;
delete test;
}
这是我为要构建的程序编写的测试。但是,为了让我有一个更清晰、更具可读性的测试,我需要一个辅助函数。这就是 setInfo 的用途。这是代码:
void setInfo(BTreeData *info, char *name, char *age, char *occupation, int
nameSize, int ageSize, int occSize) {
strncpy(info->name, name, nameSize);
strncpy(info->age, age, ageSize);
strncpy(info->occupation, occupation, occSize);
}
问题是我正在尝试设置信息的值。我正在尝试通过引用传递,以便我可以设置信息。当我检查 xCode 调试器时,它可以正常工作,直到 setInfo 函数结束。但出于某种原因,当我的代码返回 testOneBTreeLeafNode
以继续执行其余代码时,信息中的值会发生变化。它有额外不需要的垃圾,如下图所示。我对通过引用传递的理解很差。谁能赐教一下?
注意大卫的年龄和职业应该是 20 岁和学生。它有 20 和学生,但也有其他不需要的垃圾。为什么会这样?
如果有必要,这里有 BTree 结构:
//
// BTree.hpp
// CS130FinalProject
//
// Created by Lester Dela Cruz on 2/19/16.
// Copyright © 2016 Lester Dela Cruz. All rights reserved.
//
#ifndef BTree_hpp
#define BTree_hpp
#define M (5)
#define L (3)
#include <stdio.h>
struct BTreeData {
char name[20];
char age[3];
char occupation[30];
};
struct BTreeLeafNode {
BTreeData dataItems[L];
};
struct BTreeInternalNode {
char keys[M-1][20];
BTreeLeafNode *branch[M];
};
class BTree {
};
#endif /* BTree_hpp */
这是因为您没有复制终止空字符。
您正在堆上分配 BtreeData
class 的新实例。每个实例的初始副本包含随机二进制垃圾。分配在堆上的 POD 数据未用零初始化。
然后您将使用 strncpy
() 来初始化字段。要将 age
成员初始化为“20”,您要为 ageSize
传递 2,因此 strncpy
() 将复制“2”和“0”,但不会尾随的 \0 应该终止 C 风格的字符串。因此,您的调试器看不到尾随的 0,然后继续打印它找到的任何随机垃圾,因为正如我所说,class 实例从堆中分配并继承了之前在堆中的任何随机数据-分配的内存。
其他一些善意的批评,希望大家注意:
setInfo(&*info1, (char *)"Lester", (char *)"24", (char *)"student", 6, 2, 7);
首先,“&*”完全没有任何作用。这没有任何区别。
其次,不建议显式 (char *)
转换。您必须这样做的原因是因为字符串文字是 const char
s,而您的 setInfo
() 函数将 char *
作为参数。
除了您的 setInfo
() 不需要首先采用 char *
参数。让我们更改 setInfo
() 以将 const char *
作为参数,并摆脱这些丑陋、丑陋的转换。
这看起来像是大型应用程序的一部分,因此您传递显式字符串长度计数可能是有原因的,但没有实际原因。顺其自然,使用 strcpy
() 而不是 strncpy
(),忘记字符数。
更好的是,既然我们在这里谈论 C++
,让我们摆脱所有 char
数组,并用 std::string
替换它们。普通 char
数组是如此...上个世纪。
我们达成协议了吗?