用模板类纠正问题

时间:2013-03-31 01:47:05

标签: c++ c++11 compiler-errors g++

我正在实现一个名为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

1 个答案:

答案 0 :(得分:1)

看起来你的base1析构函数应该公开。您还应该将其声明为虚拟,否则将无法正确调用派生类析构函数。此外,您在base1中定义operator =并派生为private,然后在将测试代码中的一个共享ptr实例分配给另一个实例时尝试使用它们。剩下的错误与受保护的base1构造函数有关,这意味着您无法直接实例化它。如果你真的想创建base1对象,你可以使构造函数公开。