鱼C论坛

 找回密码
 立即注册
查看: 1942|回复: 0

C++堆栈类的子类出错。

[复制链接]
发表于 2014-1-28 20:28:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. /************************************************
  2. * stack_test -- Test the use of the classes    *
  3. *      stack and safe_stack.                   *
  4. ************************************************/
  5. #include <iostream>
  6. // The largest stack we can use
  7. // (private to class stack and safe_stack)
  8. const int STACK_MAX = 100;
  9. /************************************************
  10. * stack -- Class to provide a classic stack.   *
  11. *                                              *
  12. * Member functions:                            *
  13. *      push -- Push data on to the stack.      *
  14. *      pop -- Return the top item from the     *
  15. *              stack.                          *
  16. *                                              *
  17. * Warning: There are no checks to make sure    *
  18. *      that stack limits are not exceeded.     *
  19. ************************************************/
  20. class stack {
  21.     protected:
  22.         int count; // Number of items in the stack
  23.         int *data; // The stack data
  24.     public:
  25.         // Initialize the stack
  26.         stack(void): count(0)
  27.         {
  28.             data = new int[STACK_MAX];
  29.         }
  30.         // Destructor
  31.         virtual ~stack(void) {
  32.             delete data;
  33.             data = NULL;
  34.         }
  35.     private:
  36.         // No copy constructor
  37.         stack(const stack &);
  38.         // No assignment operator
  39.         stack & operator = (const stack &);
  40.     public:
  41.         // Push an item on the stack
  42.         void push(
  43.             const int item       // Item to push
  44.         ) {
  45.             data[count] = item;
  46.             ++count;
  47.         }
  48.         // Remove the an item from the stack
  49.         int pop(void) {
  50.             --count;
  51.             return (data[count]);
  52.         }
  53.         // Function to count things in
  54.         // an array of stacks
  55.         friend void stack_counter(
  56.             stack stack_array[],
  57.             const int n_stacks
  58.         );
  59. };
  60. /***********************************************
  61. * safe_stack -- Like stack, but checks for    *
  62. *      errors.                                *
  63. *                                             *
  64. * Member functions: push and pop              *
  65. *              (just like stack)              *
  66. ***********************************************/
  67. class safe_stack : public stack {
  68.     public:
  69.         const int max;  // Limit of the stack
  70.     public:
  71.         safe_stack(void): max(STACK_MAX) {};
  72.         // Destructor defaults
  73.     private:
  74.         // No copy constructor
  75.         safe_stack(const safe_stack &);
  76.         // No assignment operator
  77.         safe_stack & operator =
  78.             (const safe_stack &);
  79.     public:
  80.         // Push an item on the stack
  81.         void push(
  82.             // Data to push on the stack
  83.             const int data
  84.         ) {
  85.             if (count >= (STACK_MAX-1)) {
  86.                 std::cout << "Stack push error\n";
  87.                 exit (8);
  88.             }
  89.             stack::push(data);
  90.         }
  91.         // Pop an item off the stack
  92.         int pop(void) {
  93.             if (count <= 0) {
  94.                 std::cout << "Stack pop error\n";
  95.                 exit (8);
  96.             }
  97.             return (stack::pop());
  98.         }
  99. };
  100. /************************************************
  101. * stack_counter -- Display the count of the    *
  102. *      number of items in an array of stacks.  *
  103. ************************************************/
  104. void stack_counter(
  105.     // Array of stacks to check
  106.     stack *stack_array,
  107.     // Number of stacks to check
  108.     const int n_stacks
  109. )
  110. {
  111.     int i;
  112.     for (i = 0; i < n_stacks; ++i)
  113.     {
  114.         std::cout << "Stack " << i << " has " <<
  115.             stack_array[i].count << " elements\n";
  116.     }
  117. }
  118. // A set of very safe stacks for testing
  119. static safe_stack stack_array[5];
  120. int main()
  121. {
  122.     stack_array[0].push(0);
  123.     stack_array[1].push(0);
  124.     stack_array[1].push(1);
  125.     stack_array[2].push(0);
  126.     stack_array[2].push(1);
  127.     stack_array[2].push(2);
  128.     stack_array[3].push(0);
  129.     stack_array[3].push(1);
  130.     stack_array[3].push(2);
  131.     stack_array[3].push(3);
  132.     stack_array[4].push(0);
  133.     stack_array[4].push(1);
  134.     stack_array[4].push(2);
  135.     stack_array[4].push(3);
  136.     stack_array[4].push(4);
  137.     stack_counter(stack_array, 5);
  138.     return (0);
  139. }
复制代码
上面的代码大家可以看看,编译一下,就知道了。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.
fig257_01_0[1].jpg
Now a pointer can point to a single instance of a class or an array of objects.
fig257_02_0[1].jpg
So we have the following two rules:
  • A base pointer can point to a derived object.
  • An object pointer can point to an array of objects.

From this, we can conclude:
  • A base pointer can point to an array of derived objects.

That's wrong.
The problem is that an array of derived objects is not the same as an array of base objects.
fig257_03_0[2].jpg
So if we take a base pointer and point it a derived array, the memory layout will be wrong.
fig258_01[2].jpg
好啦,请注意!!!
我需要一个解决方案。建议使用dynamic_cast或者reinterpret_cast,不可以告诉我使用STL。
如果是要使用auto_ptr或者share_ptr一类的能解决也行。多谢多谢。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-17 14:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表