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

C++中如何用拷贝构造函数实现Yahtzee类跨类双指针的深拷贝?

Hey there! Let's break down how to handle that double pointer to your Protocol class in the Yahtzee copy constructor—since you already have the Dice dynamic array sorted, half the battle is won.

First, let's clarify: when you say "double pointer," I’m assuming you mean a Protocol** member in your Yahtzee class. This usually falls into two common use cases, so I’ll walk through both, plus key pitfalls to avoid.

First, Let’s Set the Stage (Assumed Class Structure)

I’ll start with a rough outline of what your Yahtzee class might look like, to ground the examples:

class Yahtzee {
private:
    Protocol** protocol_ptr;   // Your double pointer
    Dice* dice_array;          // Dynamic array you’ve already handled
    int dice_count;            // Size of the Dice array
    int protocol_count;        // Only needed if protocol_ptr is an array (case 2)
public:
    // Regular constructor (example)
    Yahtzee(int num_dice, int num_protocols = 1) {
        // Initialize Dice array (your working logic)
        dice_count = num_dice;
        dice_array = new Dice[dice_count];
        
        // Example init for protocol_ptr (adjust based on your actual code)
        // Case 1: Single Protocol object (pointer to pointer)
        protocol_ptr = new Protocol*;
        *protocol_ptr = new Protocol();
        
        // OR Case 2: Dynamic array of Protocol objects
        // protocol_ptr = new Protocol*[num_protocols];
        // for (int i = 0; i < num_protocols; ++i) {
        //     protocol_ptr[i] = new Protocol();
        // }
        // protocol_count = num_protocols;
    }

    // Destructor (critical to avoid leaks/memory issues)
    ~Yahtzee() {
        // Clean up Dice array
        delete[] dice_array;

        // Clean up protocol_ptr (match your constructor logic!)
        // Case 1: Single object
        delete *protocol_ptr;
        delete protocol_ptr;

        // OR Case 2: Array of objects
        // for (int i = 0; i < protocol_count; ++i) {
        //     delete protocol_ptr[i];
        // }
        // delete[] protocol_ptr;
    }

    // Your target: Copy Constructor
    Yahtzee(const Yahtzee& other);
};

Case 1: Double Pointer Points to a Single Protocol Object

If protocol_ptr is just a pointer to a single Protocol* (e.g., you use it to manage a resettable Protocol instance), your copy constructor needs to perform a deep copy at both levels:

  1. Allocate a new Protocol* container.
  2. Allocate a new Protocol instance, copying the data from the original object’s Protocol.

Here’s the code:

Yahtzee::Yahtzee(const Yahtzee& other) {
    // First, copy your Dice array (your existing working logic)
    dice_count = other.dice_count;
    dice_array = new Dice[dice_count];
    for (int i = 0; i < dice_count; ++i) {
        dice_array[i] = other.dice_array[i]; // Assumes Dice has a valid copy constructor
    }

    // Now handle the double pointer to a single Protocol
    // Step 1: Allocate a new pointer to hold the Protocol*
    protocol_ptr = new Protocol*;
    // Step 2: Deep copy the Protocol object itself (uses Protocol's copy constructor)
    *protocol_ptr = new Protocol(*(other.protocol_ptr));
}

Case 2: Double Pointer is a Dynamic Array of Protocol Objects

If protocol_ptr points to an array of Protocol* instances (e.g., multiple Protocol objects managed by Yahtzee), you’ll need to:

  1. Copy the array size from the original object.
  2. Allocate a new array of Protocol*.
  3. Iterate through the original array, deep copying each Protocol instance.

Here’s how that looks:

Yahtzee::Yahtzee(const Yahtzee& other) {
    // Copy Dice array (your existing logic)
    dice_count = other.dice_count;
    dice_array = new Dice[dice_count];
    for (int i = 0; i < dice_count; ++i) {
        dice_array[i] = other.dice_array[i];
    }

    // Copy the Protocol array (double pointer)
    protocol_count = other.protocol_count;
    // Step 1: Allocate a new array of Protocol*
    protocol_ptr = new Protocol*[protocol_count];
    // Step 2: Deep copy each Protocol object in the array
    for (int i = 0; i < protocol_count; ++i) {
        protocol_ptr[i] = new Protocol(*(other.protocol_ptr[i]));
    }
}

Critical Things to Remember

  • Protocol Must Have a Valid Copy Constructor
    If Protocol itself uses dynamic memory (e.g., its own pointers, arrays), you need to write a deep copy constructor for Protocol too. Relying on the compiler-generated one will do a shallow copy, leading to shared resources and crashes when objects are destroyed.

  • Match Destructor Logic to Copy Constructor
    The way you clean up protocol_ptr in the destructor must exactly match how you allocated it in the constructor and copy constructor. Mismatching delete vs delete[] or skipping a level of deletion will cause memory leaks or double-free errors.

  • Avoid Shallow Copy Traps
    Never just assign protocol_ptr = other.protocol_ptr—this makes both Yahtzee objects share the same underlying Protocol memory. When one object is destroyed, it’ll free that memory, leaving the other with a dangling pointer (undefined behavior!).

  • Consider Smart Pointers for Easier Management
    If you’re using C++11 or later, swap raw pointers for std::unique_ptr or std::shared_ptr to avoid manual memory management. For example:

    • Replace Protocol** (single object) with std::unique_ptr<std::unique_ptr<Protocol>>
    • Replace Protocol** (array) with std::vector<std::unique_ptr<Protocol>>
      Smart pointers handle copying/moving and destruction automatically, reducing the chance of mistakes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:37:20