簡體   English   中英

如何使用指針處理類的雙(或多個)副本構造函數

[英]How to deal with double (or multiple) copy constructors for class with pointers

有一個名為“ X”的類,如下所示:

class X {
private:
    int *ptr;
public:
    X() {
        ptr = new int[2];
        ptr[0] = 0;
        ptr[1] = 0;
    }
    X(int a, int b) {
        ptr = new int[2];
        ptr[0] = a;
        ptr[1] = b;
    }
    X(const X &val) {
        delete[] ptr;
        ptr = new int[2];
        ptr[0] = val.ptr[0];
        ptr[1] = val.ptr[1];
    }
    X get() {
        X ret(ptr[0], ptr[1]);
        return ret;
    }
};

假設存在用X v(2, 3)定義的變量X。

如果我們調用v.get() ,那就可以了。

但是,如果我們調用v.get().get() ,那就不好了。 它在復制構造函數的delete[] ptr部分中產生運行時錯誤,內容是我試圖刪除未定義的(0xcccccccc)指針。

處理此問題的一種可能選擇是使用C ++-STL,例如<array><vector> 但是我想用指針來實現。

如何使用基於指針的實現處理此運行時錯誤?

簡單的答案是,您不應該在復制構造函數中delete[] ptr ,因為它尚未初始化。 您也不需要分配中的delete[] ptr deletedelete[]應該出現的唯一位置是在析構函數中。

整理您的課程,而無需更改擁有原始指針

class X {
private:
    int *ptr;
public:
    X() : X(0, 0) { }
    X(int a, int b) : ptr(new int[2]) {
        ptr[0] = a;
        ptr[1] = b;
    }
    X(const X &val) : X(val.ptr[0], val.ptr[1]) { }
    X& operator=(const X &val)
    {
        ptr[0] = val.ptr[0];
        ptr[1] = val.ptr[1];
        return *this;
    }
    X(X&& val) : ptr(val.ptr) {
        val.ptr = nullptr;
    }
    X& operator=(X&& val) {
        std::swap(ptr, val.ptr);
        return *this;
    }        
    ~X() { delete[] ptr; }

    X get() {
        return *this;
    }
};

命名方面,如果構造函數將類的實例作為其單個(非默認)參數,則該構造函數僅是“ 復制構造函數 ”。 X::X(int, int)只是一個構造函數。 這意味着最多有4個副本構造函數(否則,在重載分辨率下它們將是模棱兩可的)

X::X(X &)
X::X(const X &)
X::X(volatile X &)
X::X(const volatile X &)

但是,除非您參加混淆競賽,否則定義一個以上的想法是一個可怕的主意

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM