我正在学习C ++,我们接受了练习,使用类模板和指针创建堆栈类。我还没有完全理解堆栈或指针的实现,所以我给了它一个去做这个类:
template <class T>
class Stack_Class {
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value) {
if (value > 0) {
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class() {
if (First_item) {
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num) {
if (item_quantity <Max_quantity) {
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop() {
if (!Empty()) {
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty() {
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity() {
return Max_quantity;
}
主要课程是:
#include <iostream>
#include "Stack_Class.h"
void main() {
Stack_Class<int> intStack(3);
intStack.Add(1);
intStack.Add(2);
intStack.Add(3);
int count = intStack.GetMax_Quantity();
for (int i = 0; i < count; i++) {
std::cout << "Pop No: " << i << " - Elemento: " << intStack.Pop() << std::endl;
}
}
虽然结果我得到的是所有随机数而不是我在intStack中给出的那些数。添加,所以我的问题是我正在这里正确实现指针吗?
答案 0 :(得分:5)
在stack
内引用Pop()
之前,您需要先递减template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
stack--;
return *stack;
}
return NULL;
}
指针:
stack[item_quantity]
您的数组访问权限stack
不起作用,因为您在Add
中增加了stack
。所以在构造之后,0xff65f96f <-- *(stack + 0)
0x0eec604f <-- *(stack + 1)
0x05be0582 <-- *(stack + 2)
0x29b9186e <-- *(stack + 3)
指向的内存看起来像这样
new
十六进制值表示在分配时同时位于存储器中的随机垃圾。这是因为1 <-- *(stack - 3)
2 <-- *(stack - 2)
3 <-- *(stack - 1)
0x29b9186e <-- *(stack + 0)
0xf66eff06 <-- *(stack + 1)
0x357eb508 <-- *(stack + 2)
分配的内存未初始化为好的东西。添加三个值后,它看起来像这样
Pop
在stack[2] = *(stack + 2)
的第一次通话中,您访问item_quantity
,因为Pop
在减去它之后为2。连续两次拨打stack[1]
访问stack[0]
和{{1}}。正如您在上面所看到的,您实际上从未实际引用您放入堆栈的值。
答案 1 :(得分:1)
您正在混合Add
方法中的指针递增语义和Pop
方法中的索引语义。
由于你需要Empty方法的索引等等,我会修复你的Add方法而不是Pop,如下所示。
否则,您最终仍会在某些方法中使用索引,但在其他方法中则不然。这对我来说不一致。
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
stack[item_quantity++] = num;
return true;
}
else return false;
}
您的代码中的另一个问题是:
stack = new T[value];
但你似乎只删除了指针中的第一个元素。这是一个有保证的(也可能是不可忽略的)内存泄漏。
即使你解决了这一切,你的代码仍然无法编译,因为你试图返回void,而C ++程序应该返回int,所以改变这个:
void main(){
...
}
为:
int main(){
...
}
...并相应地返回0之类的整数。
您还需要修复此警告:
Stack_Class.h:56:13:警告:从NULL转换为非指针类型'int'[-Wconversion-null] 返回NULL; ^
例如,将NULL更改为0。
修正了所有这些,输出如下:
Pop No: 0 - Elemento: 3
Pop No: 1 - Elemento: 2
Pop No: 2 - Elemento: 1
您还可以看到运行on ideone的代码。
为方便起见,这是修复后的整个工作代码:
template <class T>
class Stack_Class{
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value){
if (value > 0){
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class(){
if (First_item){
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty(){
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity(){
return Max_quantity;
}