-2

スマート ポインターをほぼ完成させたので (わかっています...)、それを大学の Web サイトにアップロードしました。この Web サイトでは、コードに対して多数の自動テストが実行されます。多くのテストには 2 つの問題があります。

  • メモリまたは時間の制限を超えています
  • メモリ アクセスの問題 (ヌル ポインタなど)

問題は、どのようなテストが実行されているかわかりません。私が行った自動テストの stdout を読み取ることができます。これはそこに書かれています。

In instantiation of ‘my_pointer<T>::my_pointer() [with T = tester]’:
error: no matching function for call to ‘tester::tester()’
note: candidates are:
tester::tester(my_pointer<tester>)
candidate expects 1 argument, 0 provided
tester::tester(const tester&)
candidate expects 1 argument, 0 provided

それで、奇妙な理由で my_pointer() コンストラクターを呼び出さないと思いますか? これは私のスマート ポインター クラスです。

template<class T>
class my_pointer {
    T* raw_pointer;

public:
    my_pointer() {
        raw_pointer = new T();
        raw_pointer->incRefCnt();
    }

    my_pointer(T *obj) : raw_pointer(obj) {
        if(raw_pointer != NULL) raw_pointer->incRefCnt();
    }

    my_pointer(const my_pointer<T>& smart_pointer) : raw_pointer(smart_pointer.raw_pointer) {
        if(raw_pointer != NULL) raw_pointer->incRefCnt();
    }

    T& operator*() {
        return *raw_pointer;
    }

    T* operator->() {
        return raw_pointer;
    }

    operator T*() {
        return raw_pointer;
    }

    my_pointer<T> &operator=(const my_pointer<T> &smart_pointer) {
        if(this != &smart_pointer && raw_pointer != NULL) {
            /** if this was the last reference to the given memory address */
            if (raw_pointer->decRefCnt() == 0) {
            delete raw_pointer;                    
            }

            raw_pointer = smart_pointer.raw_pointer;
            raw_pointer->incRefCnt();
        }

        return *this;
    }

    bool operator== (const T* pointer) {
        return raw_pointer == pointer;
    }

    bool operator!= (const T* pointer) {
        return raw_pointer != pointer;
    }

    bool operator== (const my_pointer<T> &smart_pointer) {
        return raw_pointer == smart_pointer.raw_pointer;
    }

    bool operator!= (const my_pointer<T> &smart_pointer) {
        return raw_pointer != smart_pointer.raw_pointer;
    }

    ~my_pointer() {
       if(raw_pointer->decRefCnt() == 0 && raw_pointer != NULL) {
           delete raw_pointer;
        }
    }
};

これは、参照をカウントできるクラスです。

class refcounted {
private:
    int count;
public:
    refcounted() : count(0) { }

    int incRefCnt() {
        return ++count;
    }

    int decRefCnt() {
        return --count;
    }
};

コードに問題はありますか? 前もって感謝します!

4

2 に答える 2

3

デストラクタで生のポインタを無条件に削除しています。これは間違っています。参照カウントをデクリメントし、ゼロになった場合にのみ削除する必要があります。

かどうかをraw_pointer->incRefCnt();確認せずにいくつかの場所で呼び出すこともできます。raw_pointerNULL

于 2015-11-01T16:02:13.487 に答える
0

あなたのコードには 2 つの問題があります。

  1. in operator=():if(raw_pointer != NULL)既に逆参照した後にチェックしますraw_pointer(上記の行で)。チェックを逆にする必要があります。

  2. デストラクタで: 最初に を呼び出して、参照カウントがゼロになった場合にdecRefCnt()のみ削除するべきではありませんか?raw_pointer

参照カウントを減らし、必要に応じて raw_pointer を削除する (AFAICS) の両方operator=()で実質的に同じコードが必要なので、その機能を新しいメソッドに抽出し、両方の場所から呼び出す方が実用的です。~my_pointer()

于 2015-11-01T16:52:11.433 に答える