2017-04-21 9 views
0

私はこの質問がここまでに尋ねられたことを知っています:Delete an object with a protected destructor。しかし、その解決策は私のためには機能しませんでした。私はまだコンパイル中にエラーが発生します。別のクラスの保護されたデストラクタを持つオブジェクトを削除する

私のプロジェクトではスマートポインタを作成することもありますが、いくつかのテストではプロテクトされたデストラクタ(一部は仮想であり、一部はありません)を持つオブジェクトが削除され、コンパイル時エラーが発生します。

私は実際にこの問題の修正をどこから始めるべきかわかりません。前もって感謝します!

これは私がしなければならないかのアイデアです:このエラーで

#include <cstddef> 

template<typename T> void DefaultDeleter(void *p) { delete static_cast<T*>(p); } 

struct ref_counter { 
    int refs; 
    void *p; 
    void (*d)(void *); 
}; 

template<typename T> class Sptr { 
    public: 
      Sptr(T *obj){ 
      c = new ref_counter; 
      c->refs = 1; 
      c->p = static_cast<void*>(obj); 
      c->d = &DefaultDeleter<T>; 
      p = p; 
     } 
     void reset(){ 
      (c->d)(c->p); 
      delete c; 
     } 
    private: 
     T *p; 
     ref_counter *c; 
}; 

class Base{ 
    public: 
     Base(){ 
      atr = new int(1); 
     } 
    protected: 
     ~Base(){ 
      delete atr; 
     } 
    private: 
     int *atr; 
}; 

int main(){ 
    Base b1; 
    Sptr<Base> s1(&b1); 
    return 0; 
} 

このコードの結果:

[email protected]:~/cs440/a3# g++ test.cpp -o test 
test.cpp: In function ‘int main()’: 
test.cpp:43:7: error: ‘Base::~Base()’ is protected within this context 
    Base b1; 
     ^~ 
test.cpp:35:3: note: declared protected here 
    ~Base(){ 
^
test.cpp: In instantiation of ‘void DefaultDeleter(void*) [with T = Base]’: 
test.cpp:17:9: required from ‘Sptr<T>::Sptr(T*) [with T = Base]’ 
test.cpp:44:19: required from here 
test.cpp:3:53: error: ‘Base::~Base()’ is protected within this context 
template<typename T> void DefaultDeleter(void *p) { delete static_cast<T*>(p); } 
                ^~~~~~ 
test.cpp:35:3: note: declared protected here 
    ~Base(){ 
+0

を行うことができます。おそらく、あなたがpublicデストラクタと 'Derived * 'ポインタを持つ' Derived'クラスを持っていれば、それについて何かできます。 – aschepler

+0

あなたは受け入れられた答えから非常に重要なメモを逃しました:*私はもちろん、Baseのデストラクタはprotectedであり、Derivedはpublicです。そうでなければ練習は意味をなさない* –

+1

とにかく、 'Sptr s1(&b1)'はスマートポインタには意味がないので、**割り当てられるべきものを自動的に割り当て解除します**。 – Jarod42

答えて

2

事はあなたのコンストラクタが破壊されることが実数型を取るということです、基本クラスのデストラクタが保護されていても、次のようなものがあります。

template<typename T> 
class Sptr { 
public: 
    template <typename U> 
    explicit Sptr(U* obj){ 
     c = new ref_counter; 
     c->refs = 1; 
     c->p = static_cast<void*>(obj); 
     c->d = &DefaultDeleter<U>; 
    } 
// ... 
}; 

次に:

class Base { 
protected: 
    ~Base() = default; 
}; 

class Derived : public Base 
{ 
public: 
    ~Derived() = default; 
}; 

あなたはええ、 `〜ベースは、()` `DefaultDeleter`からアクセスすることはできません、まあ

Sptr<Base> p{new Derived()}; 
+0

あなたは正しいです!これはまさにテストケースがしようとしていることです。あなたの助けをありがとう! – nedak96

関連する問題