马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
/************************************************
* stack_test -- Test the use of the classes *
* stack and safe_stack. *
************************************************/
#include <iostream>
// The largest stack we can use
// (private to class stack and safe_stack)
const int STACK_MAX = 100;
/************************************************
* stack -- Class to provide a classic stack. *
* *
* Member functions: *
* push -- Push data on to the stack. *
* pop -- Return the top item from the *
* stack. *
* *
* Warning: There are no checks to make sure *
* that stack limits are not exceeded. *
************************************************/
class stack {
protected:
int count; // Number of items in the stack
int *data; // The stack data
public:
// Initialize the stack
stack(void): count(0)
{
data = new int[STACK_MAX];
}
// Destructor
virtual ~stack(void) {
delete data;
data = NULL;
}
private:
// No copy constructor
stack(const stack &);
// No assignment operator
stack & operator = (const stack &);
public:
// Push an item on the stack
void push(
const int item // Item to push
) {
data[count] = item;
++count;
}
// Remove the an item from the stack
int pop(void) {
--count;
return (data[count]);
}
// Function to count things in
// an array of stacks
friend void stack_counter(
stack stack_array[],
const int n_stacks
);
};
/***********************************************
* safe_stack -- Like stack, but checks for *
* errors. *
* *
* Member functions: push and pop *
* (just like stack) *
***********************************************/
class safe_stack : public stack {
public:
const int max; // Limit of the stack
public:
safe_stack(void): max(STACK_MAX) {};
// Destructor defaults
private:
// No copy constructor
safe_stack(const safe_stack &);
// No assignment operator
safe_stack & operator =
(const safe_stack &);
public:
// Push an item on the stack
void push(
// Data to push on the stack
const int data
) {
if (count >= (STACK_MAX-1)) {
std::cout << "Stack push error\n";
exit (8);
}
stack::push(data);
}
// Pop an item off the stack
int pop(void) {
if (count <= 0) {
std::cout << "Stack pop error\n";
exit (8);
}
return (stack::pop());
}
};
/************************************************
* stack_counter -- Display the count of the *
* number of items in an array of stacks. *
************************************************/
void stack_counter(
// Array of stacks to check
stack *stack_array,
// Number of stacks to check
const int n_stacks
)
{
int i;
for (i = 0; i < n_stacks; ++i)
{
std::cout << "Stack " << i << " has " <<
stack_array[i].count << " elements\n";
}
}
// A set of very safe stacks for testing
static safe_stack stack_array[5];
int main()
{
stack_array[0].push(0);
stack_array[1].push(0);
stack_array[1].push(1);
stack_array[2].push(0);
stack_array[2].push(1);
stack_array[2].push(2);
stack_array[3].push(0);
stack_array[3].push(1);
stack_array[3].push(2);
stack_array[3].push(3);
stack_array[4].push(0);
stack_array[4].push(1);
stack_array[4].push(2);
stack_array[4].push(3);
stack_array[4].push(4);
stack_counter(stack_array, 5);
return (0);
}
上面的代码大家可以看看,编译一下,就知道了。safe_stack不安全,哈哈。求解决办法。
StackOverflow和Yahoo Ask上面的答案已经把我搞蒙了。书上的解释也好乱。求大神。
下面是书上的解释:
We have an array of a derived class called safe stack. In C++, you can use a base class pointer (stack*) to point to a derived class (safe_stack). The system will see only the base part of the object, but you can still point to it.
Now a pointer can point to a single instance of a class or an array of objects.
So we have the following two rules: From this, we can conclude: That's wrong. The problem is that an array of derived objects is not the same as an array of base objects.
So if we take a base pointer and point it a derived array, the memory layout will be wrong. 好啦,请注意!!! 我需要一个解决方案。建议使用dynamic_cast或者reinterpret_cast,不可以告诉我使用STL。 如果是要使用auto_ptr或者share_ptr一类的能解决也行。多谢多谢。
|