You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++链式栈拷贝构造函数求助:未正确使用拷贝构造函数

Fixing Your Copy Constructor Usage & Missing lStack2 Display Issue

Hey there! Let's break down why your copy constructor isn't working as intended and why lStack2 isn't showing up. Copy constructors get tricky when dealing with dynamic memory, so let's walk through common pitfalls and fixes step by step.

First: When Does the Copy Constructor Actually Get Called?

A lot of folks mix up copy construction and assignment—these are totally different operations! The copy constructor only triggers when you initialize a new object using an existing one:

  • Direct initialization: Stack lStack2(lStack1);
  • Copy initialization: Stack lStack2 = lStack1; (this is still initialization, not assignment!)

If you write something like Stack lStack2; lStack2 = lStack1;, that calls the assignment operator, not the copy constructor. That's a super common mistake!

Common Reasons Your lStack2 Isn't Displaying

1. You're Using a Shallow Copy (Default Copy Constructor)

If your class uses dynamically allocated memory (like a heap array for the stack), the compiler-provided default copy constructor does a "shallow copy": it copies pointer values, not the actual data. This means lStack1 and lStack2 end up pointing to the same chunk of memory. When one object is destroyed, it frees that memory—leaving the other with a dangling pointer. Trying to display lStack2 then accesses invalid memory, causing crashes, garbage output, or nothing at all.

2. Your Copy Constructor Isn't Implemented Correctly

Even if you wrote a copy constructor, it might have issues:

  • The parameter isn't a const reference: It should look like Stack(const Stack& other)—using a value parameter triggers infinite recursion (since passing by value requires copying the object, which calls the copy constructor again).
  • You aren't allocating new memory for the copied object: For dynamic members, you need to create a new memory block and copy each element over (this is a "deep copy").

Example Fix for a Stack Class

Let's assume your Stack class uses a dynamic array. Here's how to implement a proper copy constructor and supporting functions:

Step 1: Correct Class Definition with Deep Copy Constructor

#include <iostream>
using namespace std;

class Stack {
private:
    int* arr;       // Dynamic array for stack elements
    int top;        // Index of top element
    int capacity;   // Max size of the stack

public:
    // Constructor
    Stack(int size = 10) : capacity(size), top(-1) {
        arr = new int[capacity];
    }

    // ✅ Proper Deep Copy Constructor
    Stack(const Stack& other) {
        // Copy basic member values
        capacity = other.capacity;
        top = other.top;
        // Allocate NEW memory for the copied stack
        arr = new int[capacity];
        // Copy every element from the original stack
        for (int i = 0; i <= top; ++i) {
            arr[i] = other.arr[i];
        }
    }

    // ✅ Destructor to free dynamic memory
    ~Stack() {
        delete[] arr;
    }

    // ✅ Assignment Operator (Rule of Three: required with copy constructor + destructor)
    Stack& operator=(const Stack& other) {
        // Prevent self-assignment (avoids deleting memory we need)
        if (this != &other) {
            // Free current memory first
            delete[] arr;
            // Copy values and allocate new memory
            capacity = other.capacity;
            top = other.top;
            arr = new int[capacity];
            // Copy elements
            for (int i = 0; i <= top; ++i) {
                arr[i] = other.arr[i];
            }
        }
        return *this;
    }

    // Push element to stack
    void push(int val) {
        if (top < capacity - 1) {
            arr[++top] = val;
        }
    }

    // Your display function (fixed to handle empty stacks)
    void display() const {
        if (top == -1) {
            cout << "Stack is empty" << endl;
            return;
        }
        cout << "Stack elements: ";
        for (int i = top; i >= 0; --i) {
            cout << arr[i] << " ";
        }
        cout << endl;
    }
};

Step 2: Correctly Trigger the Copy Constructor in main

Now initialize lStack2 properly to trigger the copy constructor:

int main() {
    Stack lStack1(5);
    lStack1.push(10);
    lStack1.push(20);
    lStack1.push(30);
    
    cout << "lStack1: ";
    lStack1.display();

    // ✅ This triggers the copy constructor (initializing lStack2 with lStack1)
    Stack lStack2(lStack1);
    // OR: Stack lStack2 = lStack1; (also works for copy initialization)
    
    cout << "lStack2 (copied from lStack1): ";
    lStack2.display();

    // If you need to assign later, use the overloaded assignment operator
    // Stack lStack3;
    // lStack3 = lStack1; // Calls operator=, which we implemented above

    return 0;
}

Key Takeaways

  • Always use a deep copy for classes with dynamic memory to avoid dangling pointers.
  • Ensure your copy constructor uses a const reference parameter.
  • Trigger the copy constructor via initialization, not assignment.
  • Follow the Rule of Three: if you implement a copy constructor, you also need a destructor and an overloaded assignment operator.

内容的提问来源于stack exchange,提问作者Rafael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:16:13