在每个场景中会发生什么以及如何实现?

时间:2015-03-11 01:26:57

标签: c++

我定义了Stack 。现在,我想通过将其传递给reverseStack函数来反转堆栈。我想知道各种情况下会发生什么。最后,最好的方法是什么。

堆叠实施:

class Stack {
        public:
            Stack() {
                a = new int[25];
                capacity = 25;
            }
            Stack(int size) {
                a = new int[size];
                capacity = size;
            }
            ~Stack() {
                delete[] a;
            }
            void push(int x) {
                if (index == capacity - 1) {
                    cout << "\n\nThe stack is full. Couldn't insert " << x << "\n\n";
                    return;
                }
                a[++index] = x;
            }
            int pop() {
                if (index == -1) {
                    cout << "\n\nNo elements to pop\n\n";
                    return -1;
                }
                return a[index--];
            }

            int top();
            bool isEmpty();
            void flush();

        private:
            int capacity ;
            int* a;
            int index = -1; // Index of the top most element
    };

SCENARIO-1:

void reverseStack(Stack& s) {
    Stack s2;
    while (!s.isEmpty()) {
        s2.push(s.pop());
    }
    s = s2;
}

int main() {
    Stack s;
    s.push(1);
    s.push(2);
    s.push(3);
    reverseStack(s);
    return 0;
}

SCENARIO-2:

Stack reverseStack(Stack& s) {
    Stack s2;
    while (!s.isEmpty()) {
        s2.push(s.pop());
    }
    return s2;
}

int main() {
    Stack s;
    s.push(1);
    s.push(2);
    s.push(3);
    s = reverseStack(s);
    return 0;
}

在场景-1(失败)中,函数内的s = s2是什么意思?我认为这是一个成员明智的副本。如果数据成员不涉及指针(int* a),它会起作用吗?

由于同样的原因,场景-2也失败了。我如何完成我想要的目标?

我应该有一个拷贝构造函数(我该如何实现它?)。如何重载赋值运算符(同样,我该如何实现?)?

我试图用这种方式实现它:

Stack Stack::operator = (Stack s) {
    capacity = s.capacity;
    int* a = new int[capacity];
    for (int i = 0; i < capacity; i++) {
        a[i] = s.a[i];
    }
    index = s.index;
    return *this;
}

1 个答案:

答案 0 :(得分:1)

关于方案,最好的方案是第二个,因为return value optimization,即:编译器可能会优化掉返回值的副本并防止不必要的副本。

现在,您在班级中使用动态内存,这意味着复制构造函数赋值运算符的默认实现将不能为你工作

复制构造函数,它与您编写的赋值运算符几乎相同

Stack::Stack(const Stack& s)
 : capacity(s.capacity)
 , a(new int[capacity])
 , index(s.index)
{ // std::copy is just a shortcut, what you're doing is fine too
    std::copy(s.a, s.a + capacity, a);
}

你写的赋值运算符有两种错误:

  1. 它应该通过引用
  2. 返回Stack个对象
  3. 参数应为const reference
  4. 剩下的就是好的

    Stack& Stack::operator = (const Stack& s) {
        capacity = s.capacity;
        a = new int[capacity];
        for (int i = 0; i < capacity; i++) { // or std::copy
            a[i] = s.a[i];
        }
        index = s.index;
        return *this;
    }
    

    <强>更新

    暂时实现reverseStack函数(没有副作用),假设索引包含堆栈中的实际项目数

    Stack reverseStack(const Stack& s) {
        Stack s2(s.capacity);
        for (int i = 0; i < s2.index; ++i) {
            s2.a[i] = s2.a[s2.index -i];
        }
        return s2;
    }
    

    更新感谢user657267指出int* a = new int[capacity];错误