为更好的编程实践征求意见 P>当我学习C++时,我开始将一些常见的数据结构作为实践的一种形式来实现。 第一个是堆栈(这是第一个想到的)。 我已经做了一些编程,它正在工作,但现在我需要一些输入,我应该做什么,否则。例如删除某些内容或其他专业提示。我应该做些什么,为什么 template <class T> class Stack { private: int* values; int capacity; int itemsOnStack; public: /////////////////// Stack() { Stack(32); } /////////////////// Stack(const int sz) { values = new T[sz]; capacity = sz; itemsOnStack = 0; } ~Stack() { values = 0; // delete? } //////////////////// void Push(const T& item) { *(values + itemsOnStack) = item; itemsOnStack++; if(itemsOnStack > capacity) { capacity *= 2; T* temp = new T[capacity]; temp = values; values = new T[capacity]; values = temp; } } /////////////////// T Pop() { if(itemsOnStack > 0) { int current = --itemsOnStack; return *(values + current); } return NULL; // ? good? } /////////////////// T Peek() { if(itemsOnStack > 0) { int current = itemsOnStack - 1; return *(values + current); } return NULL; // find something better here or shouldnt? } /////////////////// int Count() { return itemsOnStack; } /////////////////// int Capacity() { return capacity; } /////////////////// bool IsEmpty() { return itemsOnStack == 0; } }; 模板 类堆栈 { 私人: int*值; 国际能力; int itemsOnStack; 公众: /////////////////// 堆栈() { 堆栈(32); } /////////////////// 堆栈(const int sz) { 值=新的T[sz]; 容量=sz; itemsOnStack=0; } ~Stack() { 数值=0; //删除? } //////////////////// 无效推送(常数T和项目) { *(值+项堆栈)=项; itemsOnStack++; 如果(itemsOnStack>capacity) { 容量*=2; T*温度=新的T[容量]; 温度=数值; 值=新的T[容量]; 数值=温度; } } /////////////////// T Pop() { 如果(itemsOnStack>0) { int current=--itemsOnStack; 返回*(值+当前值); } 返回NULL;//?好吗? } /////////////////// T Peek() { 如果(itemsOnStack>0) { int current=itemsOnStack-1; 返回*(值+当前值); } return NULL;//在这里找到更好的还是不应该? } /////////////////// 整数计数() { 返回itemsOnStack; } /////////////////// 整数容量() { 返回能力; } /////////////////// 布尔是空的 { 返回itemsOnStack==0; } };
您可能应该删除析构函数中的为更好的编程实践征求意见 P>当我学习C++时,我开始将一些常见的数据结构作为实践的一种形式来实现。 第一个是堆栈(这是第一个想到的)。 我已经做了一些编程,它正在工作,但现在我需要一些输入,我应该做什么,否则。例如删除某些内容或其他专业提示。我应该做些什么,为什么 template <class T> class Stack { private: int* values; int capacity; int itemsOnStack; public: /////////////////// Stack() { Stack(32); } /////////////////// Stack(const int sz) { values = new T[sz]; capacity = sz; itemsOnStack = 0; } ~Stack() { values = 0; // delete? } //////////////////// void Push(const T& item) { *(values + itemsOnStack) = item; itemsOnStack++; if(itemsOnStack > capacity) { capacity *= 2; T* temp = new T[capacity]; temp = values; values = new T[capacity]; values = temp; } } /////////////////// T Pop() { if(itemsOnStack > 0) { int current = --itemsOnStack; return *(values + current); } return NULL; // ? good? } /////////////////// T Peek() { if(itemsOnStack > 0) { int current = itemsOnStack - 1; return *(values + current); } return NULL; // find something better here or shouldnt? } /////////////////// int Count() { return itemsOnStack; } /////////////////// int Capacity() { return capacity; } /////////////////// bool IsEmpty() { return itemsOnStack == 0; } }; 模板 类堆栈 { 私人: int*值; 国际能力; int itemsOnStack; 公众: /////////////////// 堆栈() { 堆栈(32); } /////////////////// 堆栈(const int sz) { 值=新的T[sz]; 容量=sz; itemsOnStack=0; } ~Stack() { 数值=0; //删除? } //////////////////// 无效推送(常数T和项目) { *(值+项堆栈)=项; itemsOnStack++; 如果(itemsOnStack>capacity) { 容量*=2; T*温度=新的T[容量]; 温度=数值; 值=新的T[容量]; 数值=温度; } } /////////////////// T Pop() { 如果(itemsOnStack>0) { int current=--itemsOnStack; 返回*(值+当前值); } 返回NULL;//?好吗? } /////////////////// T Peek() { 如果(itemsOnStack>0) { int current=itemsOnStack-1; 返回*(值+当前值); } return NULL;//在这里找到更好的还是不应该? } /////////////////// 整数计数() { 返回itemsOnStack; } /////////////////// 整数容量() { 返回能力; } /////////////////// 布尔是空的 { 返回itemsOnStack==0; } };,c++,stack,C++,Stack,您可能应该删除析构函数中的值,而不仅仅是将其设置为0 在push方法中,不能这样调整数组的大小 有关调整阵列大小的更多信息:举几个例子,以及John提到的内容: 1.)使用初始化列表 2.)在适用的情况下使用常量成员函数。 3.)使用更符合标准的函数名。(空的()而不是空的()) 4.)您有大量内存泄漏。销毁析构函数中的内存Push():在写入数组之前,应检查数组的大小对代码进行了第一次修复: template <class T> class Stack { private:
值,而不仅仅是将其设置为0
在push
方法中,不能这样调整数组的大小
有关调整阵列大小的更多信息:举几个例子,以及John提到的内容:
1.)使用初始化列表
2.)在适用的情况下使用常量成员函数。
3.)使用更符合标准的函数名。(空的()而不是空的())
4.)您有大量内存泄漏。销毁析构函数中的内存Push()
:在写入数组之前,应检查数组的大小对代码进行了第一次修复:
template <class T>
class Stack
{
private:
int* values;
int capacity;
int itemsOnStack;
public:
//Stack() :
//{
// Stack(32); // doesn't do what you expect. This would create an unnamed temporary stack object
//}
Stack(const int sz = 32) // C++ doesn't yet have delegating constructors. You can't call one ctor from another. But in this case, a simple default parameter can be used instead
: values(new T[sz]), capacity(sz), itemsOnStack() {} // use the initializer list for initializing members
~Stack()
{
delete[] values; // you allocated it, so you delete it as well
}
////////////////////
void Push(const T& item)
{
values[itemsOnStack] = item; // cleaner syntactically than your version
// *(values + itemsOnStack) = item;
++itemsOnStack; // prefer pre-increment by default.
if(itemsOnStack > capacity) // you need to check this before writing the element. Move this to the top of the function
{
int newCapacity = capacity * 2;
// what's this supposed to do? You're just copying pointers around, not the contents of the array
T* temp = new T[newCapacity ];
std::copy(values, values+capacity, temp); // copy the contents from the old array to the new one
delete[] values; // delete the old array
values = temp; // store a pointer to the new array
capacity = newCapacity;
}
}
///////////////////
T Pop()
{
T result = Peek(); // you've already got a peek function. Why not use that?
--itemsOnStack;
return result;
}
///////////////////
T Peek()
{
if(itemsOnStack > 0)
{
int current = itemsOnStack - 1;
return values[current]; // again, array syntax is clearer than pointer arithmetics in this case.
}
// return NULL; // Only pointers can be null. There is no universal "nil" value in C++. Throw an exception would be my suggestion
throw StackEmptyException();
}
///////////////////
int Count()
{
return itemsOnStack;
}
///////////////////
int Capacity()
{
return capacity;
}
///////////////////
bool IsEmpty()
{
return itemsOnStack == 0;
}
};
模板
类堆栈
{
私人:
int*值;
国际能力;
int itemsOnStack;
公众:
//堆栈():
//{
//Stack(32);//没有达到预期效果。这将创建一个未命名的临时堆栈对象
//}
堆栈(const int sz=32)//C++没有委托构造函数。不能从另一个调用一个cTor。但是在这种情况下,可以使用一个简单的默认参数来代替。
:value(new T[sz])、capacity(sz)、itemsOnStack(){}//使用初始值设定项列表初始化成员
~Stack()
{
delete[]value;//您分配了它,所以您也删除了它
}
////////////////////
无效推送(常数T和项目)
{
值[itemsOnStack]=item;//语法上比您的版本更清晰
//*(值+项堆栈)=项;
++itemsOnStack;//默认情况下首选预增量。
if(itemsOnStack>capacity)//在写入元素之前需要检查此项。将其移动到函数的顶部
{
int newCapacity=容量*2;
//这应该做什么?你只是在复制指针,而不是数组的内容
T*temp=新T[新容量];
std::copy(值,值+容量,临时);//将内容从旧数组复制到新数组
delete[]值;//删除旧数组
values=temp;//存储指向新数组的指针
容量=新容量;
}
}
///////////////////
T Pop()
{
T result=Peek();//您已经有了一个Peek函数。为什么不使用它呢?
--项目栈;
返回结果;
}
///////////////////
T Peek()
{
如果(itemsOnStack>0)
{
int current=itemsOnStack-1;
返回值[current];//同样,在本例中,数组语法比指针算术更清晰。
}
//返回空;//指针只能是空的。C++中没有通用的“nIL”值。抛出异常是我的建议。
抛出StackEmptyException();
}
///////////////////
整数计数()
{
返回itemsOnStack;
}
///////////////////
整数容量()
{
返回能力;
}
///////////////////
布尔是空的
{
返回itemsOnStack==0;
}
};
有待解决的问题:
复制构造函数和赋值运算符。目前,如果我尝试这样做,它将可怕地崩溃:
Stack<int> s;
Stack<int> t = s; // no copy constructor defined, so it'll just copy the pointer. Then both stacks will share the same internal array, and both will try to delete it when they're destroyed.
Stack<int> u;
u = s; // no assignment operator, so much like above, it'll blow up
stacks;
堆栈t=s;//没有定义复制构造函数,所以它只复制指针。然后,两个堆栈将共享同一个内部数组,当它们被销毁时,都将尝试删除它。
堆栈u;
u=s;//没有赋值操作符,就像上面那样,它会爆炸的
常数正确性:
我是否应该能够在常量堆栈上调用Peek()
或Count()
对象生存期:
从堆栈中弹出元素不会调用元素的析构函数。推送元素不会调用元素的构造函数。只需扩展数组,即可立即为所有新元素调用默认构造函数。当用户插入一个元素而不是之前,应该调用构造函数,当删除一个元素时,应该立即调用析构函数
以及,呃,适当的测试:
我没有以任何方式编译、运行、测试或调试过它。因此,我很可能错过了一些bug,并引入了一些新bug 你知道吗
class Noisy {
public:
Noisy() { std::cout << "Constructor" << std::endl; }
~Noisy() { std::cout << "Destructor" << std::endl; }
Noisy& operator=(const Noisy& other) {std::cout << "Assign" << std::endl; }
Noisy(const Noisy& other) {std::cout << "Copy constructor" << std::endl; }
};
Stack<Noisy> stack(10);
stack.Push(Noisy());
Stack<Noisy> otherStack(stack);
Stack<Noisy> thirdStack;
thirdStack=stack;
int *m_values;
int m_capactity;
*(values + itemsOnStack) = item;
values[itemsOnStack] = item;