0

我正在实现一个名为 Sprt 的类(基本上是一个智能指针作为练习),下面是声明。为了清楚起见,我省略了实现。还有2个类来测试它。我已经包含了他们的代码。但是当我在函数中编写测试代码时,basic_tests_1会出现编译器错误。我不清楚如何解决它。有什么问题?

#include <iostream>
#include <stdio.h>
#include <assert.h>

namespace my {
    template <class T>
    class Sptr {
    private:
        //some kind of pointer
            //one to current obj
        T obj;
        size_t reference_count;
            //one to original obj
    public:
        Sptr();

        template <typename U> 
        Sptr(U *);

        Sptr(const Sptr &);

        template <typename U> 
        Sptr(const Sptr<U> &);

        template <typename U> 
        Sptr<T> &operator=(const Sptr<U> &);

        void reset();

        T* operator->() const
        {return &obj;};

        T& operator*() const
        {return obj;};

        T* get() const
        {return &obj;};

    };
}


using namespace std;
using namespace my;
/* Basic Tests 1 ================================================================================ */

class Base1 {
    protected:
        Base1() : derived_destructor_called(false) {
            printf("Base1::Base1()\n");
        }
    private:
        Base1(const Base1 &); // Disallow.
        Base1 &operator=(const Base1 &); // Disallow.
    protected:
        ~Base1() {
            printf("Base1::~Base1()\n");
            assert(derived_destructor_called);
        }
    protected:
        bool derived_destructor_called;
};

class Derived : public Base1 {
        friend void basic_tests_1();
    private:
        Derived() {}
        Derived(const Derived &); // Disallow.
        Derived &operator=(const Derived &); // Disallow.
    public:
        ~Derived() {
            printf("Derived::~Derived()\n");
            derived_destructor_called = true;
        }
        int value;
};


void basic_tests_1() {


    // Test deleting through original class.
    {
        // Base1 created directly with Derived *.
        {
            Sptr<Base1> sp(new Derived);
            {
                // Test copy constructor.
                Sptr<Base1> sp2(sp);
            }
        }
        // Base1 assigned from Sptr<Derived>.
        {
            Sptr<Base1> sp2;
            {
                Sptr<Derived> sp(new Derived);
                // Test template copy constructor.
                Sptr<Base1> sp3(sp);
                sp2 = sp;
                sp2 = sp2;
            }
        }
    }
}

int main(int argc, char *argv[]) {

    cout << "Hello world";
    basic_tests_1();

    return 0;
}

这是编译器错误:

Sptr.cpp: In destructor ‘my::Sptr<Base1>::~Sptr()’:
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected
Sptr.cpp:8:8: error: within this context
Sptr.cpp: In function ‘void basic_tests_1()’:
Sptr.cpp:142:39: note: synthesized method ‘my::Sptr<Base1>::~Sptr()’ first required here 
Sptr.cpp: In member function ‘my::Sptr<Base1>& my::Sptr<Base1>::operator=(const my::Sptr<Base1>&)’:
Sptr.cpp:107:16: error: ‘Base1& Base1::operator=(const Base1&)’ is private
Sptr.cpp:8:8: error: within this context
Sptr.cpp: In function ‘void basic_tests_1()’:
Sptr.cpp:156:23: note: synthesized method ‘my::Sptr<Base1>& my::Sptr<Base1>::operator=(const my::Sptr<Base1>&)’ first required here 
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr(U*) [with U = Derived; T = Base1]’:
Sptr.cpp:142:39:   required from here
Sptr.cpp:102:9: error: ‘Base1::Base1()’ is protected
Sptr.cpp:56:20: error: within this context
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected
Sptr.cpp:56:20: error: within this context
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr(const my::Sptr<T>&) [with T = Base1]’:
Sptr.cpp:145:35:   required from here
Sptr.cpp:102:9: error: ‘Base1::Base1()’ is protected
Sptr.cpp:61:38: error: within this context
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected
Sptr.cpp:61:38: error: within this context
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr() [with T = Base1]’:
Sptr.cpp:150:25:   required from here
Sptr.cpp:102:9: error: ‘Base1::Base1()’ is protected
Sptr.cpp:50:16: error: within this context
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected
Sptr.cpp:50:16: error: within this context
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr(U*) [with U = Derived; T = Derived]’:
Sptr.cpp:152:45:   required from here
Sptr.cpp:120:9: error: ‘Derived::Derived()’ is private
Sptr.cpp:56:20: error: within this context
4

1 回答 1

1

Looks like your base1 destructor should be made public. You should also declare it as virtual as well or the derived class destructor will not be called correctly. Also, you are defining the operator= in base1 and derived as private and then trying to use them when you assign one instance of your shared ptr to another in the test code. The remaining errors relate to the base1 constructor being protected, which means you can't instantiate it directly. You could make the constructor public if you really want to create base1 objects.

于 2013-03-31T01:52:58.080 回答