我无法弄清楚我做错了什么?我有一个有私人数据的课程:
static const int SIZE = 101;
int *ptr;
int set [SIZE];
我有2个构造函数。一个是将数组设置为0的默认构造函数。 另一个需要5个参数并将数组中的5个值设置为1。 我需要打印这个数组。当我在构造函数中时,一切正常,当我做cout<<在构造函数内部结果是正确的。但是当我尝试使用功能打印时。结果是垃圾。我做错了什么?
IntegerSet::IntegerSet() //default constructor
{
int set[SIZE] = {0};
ptr = set;
cout << "Default Constructor: " << endl;
for (int i =0; i<SIZE ;i++)
{
cout << set[i] << " ";
}
cout << endl;
}
IntegerSet::IntegerSet(int a, int b, int c, int d, int e)
{
int set[SIZE] = {0};
ptr = set;
ptr[a] = ptr[b] = ptr[c] = ptr[d] = ptr[e] = 1;
cout << "Constructor with 5 parametrs: " << endl;
for (int i =0; i<SIZE ;i++)
{
cout << ptr[i] << " ";
}
cout << endl;
}
void IntegerSet::print() const
{
bool flag = false;
cout << "I am in print: " << endl;
for (int i=0;i<SIZE;i++)
{
if (ptr[i]==1)
{
cout << i << " ";
flag = true;
}
}
if (flag == false)
cout << "-----";
cout << endl;
}
void main()
{
IntegerSet s1;
IntegerSet s2(1,50,10,22,98);
s2.print();
}
答案 0 :(得分:6)
每个构造函数都声明一个名为set
的新数组,它会隐藏类成员。
答案 1 :(得分:1)
您正在设置ptr来设置在构造函数中定义的设置,而不是设置为类变量的设置。在构造函数中更改以下内容:
int set[SIZE] = {0};
ptr = set;
到
set[SIZE-1] = {0};
ptr = set;
答案 2 :(得分:1)
除了my other answer之外,我的建议还与代码的质量和可维护性有关。您应该使用std::array
等容器作为编译时数组,并使用成员初始化列表来初始化数据成员。
您误解了以下代码行将set
的内容设置为0。
int set[SIZE] = {0};
当它覆盖set
类中的私有数据成员IntegerSet
并在构造函数中创建局部变量时。这就是为什么你应该使用STL容器来实现这些功能的原因之一。例如:
#include <array> // for std::array
class IntegerSet
{
private:
std::array<int, 101> set;
public:
IntegerSet()
: set() // zero-initializes each element
{
for (auto val : set)
std::cout << val " ";
std::cout << std::endl;
}
IntegerSet(int a, int b, int c, int d, int e)
: set()
{
set[a] = set[b] = set[c] = set[d] = set[e] = 1;
for (auto val : set)
std::cout << val " ";
std::cout << std::endl;
}
};
答案 3 :(得分:0)
您也将int set[SIZE] = {0};
放在构造函数中,它在堆栈上定义了一个本地set
(这个'隐藏'私有成员变量,也称为set
)。
如果您正在尝试set[SIZE] = 0
(将set的最后一个元素设置为0),那么您有第二个错误:您正在访问set
越界(C和C ++中的数组) 0索引。因此大小为5的数组具有有效索引(0,1,2,3和4)。你应该做set[SIZE-1] = 0
。或者更好的是,使用std::vector
或std::array
(C ++ 11)而不是C风格的数组。
答案 4 :(得分:0)
数组set
是构造函数的本地。因此,当控件退出构造函数时,指向ptr
的指针set
,稍后指向NULL,因为数组set
不存在。
使用作为实例变量的数组set
,以便在构造函数和set
方法中具有相同的print
实例。
IntegerSet::IntegerSet() //default constructor
{
set[SIZE-1] = {0};
ptr = set;
cout << "Default Constructor: " << endl;
for (int i =0; i<SIZE ;i++)
{
cout << set[i] << " ";
}
cout << endl;
}
IntegerSet::IntegerSet(int a, int b, int c, int d, int e)
{
set[SIZE-1] = {0};
ptr = set;
ptr[a] = ptr[b] = ptr[c] = ptr[d] = ptr[e] = 1;
cout << "Constructor with 5 parametrs: " << endl;
for (int i =0; i<SIZE ;i++)
{
cout << ptr[i] << " ";
}
cout << endl;
}
答案 5 :(得分:0)
以下是垃圾输出的说明:
ptr[a] = ptr[b] = ptr[c] = ptr[d] = ptr[e] = 1;
// ...
for (int i = 0; i < SIZE; i++)
{
cout << ptr[i] << " ";
}
在main方法中,您使用了参数1,50,10,22和98.因此上例中的第一行等同于:
ptr[1] = ptr[50] = ptr[10] = ptr[22] = ptr[98] = 1;
这并没有错。问题是它下面发生的事情。在for()
循环中,您尝试将ptr
从其第一个索引(0
)迭代到SIZE
。您只给出了数组中5个位置的值,因此其他值未初始化。这会导致程序出现未定义的行为,并且是导致garabage输出的原因。
您应该分别使用索引打印值。
但是直到你能告诉我们你这样做的原因是什么,我不能建议一个更好的替代方法。