我有一个创建模板容器类的赋值,该类具有可以增加和减少的动态数组。当显示数组时,对于数组中扩展它的元素,我得到垃圾数字或根本没有数字(因此如果它在第五个元素上展开,则在我输入第六个元素后,该值将变为垃圾)。当我尝试删除元素时,我收到Debug Assertion Failed错误。
这是我的代码:
template <class T> class container {
public:
container(); // constructor
// Post-condition: count is set to -1 and dynamic array size set to 5
~container(); //destructor
void insert(T &n);
// Pre-condition: a value is passed to the function
// Post-condition: if data array is not full, increment count by 1 and insert the value in the array
// Otherwise, display "Container full! No insertion is made."
void remove();
//Post-condition: if data array is not empty, remove the data[count] element in data array and decrement count by 1;
//otherwise, display a message "Container empty! Nothing is removed from it."
void display();
// Post-condition: if the array is not empty, displays all values in data array similar to the sample output;
//Otherwise, display the message “Container is now empty!"
void fillarray(container c);
//pre-condition: a container c is passed to the function
//post-condition: dynamic array of chosen type is created and filled continuously with user entered values
private:
bool empty;
//Post-condition: returns true is the array is empty, otherwise returns false
T *data; // dynamically allocated array used to store or contain the inserted values
int count; // indicates how many values have been inserted
int max;
};
template <class T> container<T>::container()
{
count = -1;
max = 5;
data = new T[max];
assert(data != NULL);
}
template <class T> container<T>::~container()
{
delete [] data;
}
template <class T> void container<T>::insert(T &n)
{
if (count >= (max - 1))
{
max = max * 2;
cout << "\nContainer full! Array size is increased by " << max/2 << ".";
T *temp = new T[max];
assert(temp != NULL);
for (int i = 0; i < count; i++)
temp[i] = data[i];
delete [] data;
data = temp;
count++;
data[count] = n;
}
else
count++;
data[count] = n;
}
template <class T> void container<T>::remove()
{
empty = count < 0;
if (empty == 1)
{
cout << "\nContainer empty! Nothing is removed from it.";}
else
{
count--;
T *temp1 = new T[max];
assert(temp1 != NULL);
for (int i = 0; i < count; i++)
temp1[i] = data[i];
delete [] data;
data = temp1;
}
}
template <class T> void container<T>::display()
{
empty = count < 0;
if (empty == 1)
{
cout << "\nContainer is now empty!";}
else
{
for (int i = 0; i <= count; ++i)
cout << " " << data[i];
}
}
template <class T> void container<T>::fillarray(container c)
{
char ans;
do
{
T value;
cout << "\nEnter a value:";
cin >> value;
c.insert(value);
cout << "\nAfter inserting, the \"container\" contains:" << endl;
c.display();
cout << "\nEnter more? (Y/y or N/n)";
cin >> ans;
} while (ans == 'Y' || ans == 'y');
for (int i = 0; i <= count; i++)
{
c.remove();
cout << "\nAfter removing a value from it, the \"container\" contains:" << endl;
c.display();
cout << endl;
}
}
// The main driver function to be used to test implementation
int main()
{
char choice;
cout << "\nEnter S for string container, D for double";
cin >> choice;
if (choice == 'S' || choice == 's')
{
container<string> c;
c.display();
c.fillarray(c);
}
else if(choice == 'D' || choice == 'd')
{
container<double> c;
c.display();
c.fillarray(c);
}
return 0;
}
答案 0 :(得分:2)
template <class T> void container<T>::fillarray(container c)
{
//...
}
此功能实际上涉及两个container<T>
个对象:*this
和c
。
由于您“按值传递”(函数参数不是参考),c
中的fillarray
被创建为c
中原始main
的副本。在fillarray
中修改c
,删除和更改c.data
,但this->data
仍包含指向原始存储的悬空指针。不久之后,你会得到不确定的行为;幸运的是,发生了很多坏事,你可以说出错了。
根据Rule of Three (Plus Two),如果类有析构函数,您可能不应该允许编译器生成默认的复制构造函数和复制赋值,您可能需要考虑实现移动构造函数并移动赋值。 / p>
满足该规则的最简单,有时最好的方法是禁用复制:
template <class T> class container
{
public:
container(container const&) = delete;
container& operator=(container const&) = delete;
//...
};
然后编译器会确保你不小心制作副本并让自己陷入这种麻烦。
答案 1 :(得分:0)
通过引用最大索引而不是条目数来使生活变得混乱。但是,使用您的方案,插入中的这一行是奇数:
for (int i = 0; i < count; i++)
因为这不会复制最终条目。