【问题标题】:correcting problems with template class纠正模板类的问题
【发布时间】:2013-03-31 01:47:05
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 它仍然有从错误‘Base1&amp; Base1::operator=(const Base1&amp;)’ is private到下面的错误。如果我也公开所有方法,则此错误仍然存​​在。
    • +1 使析构函数虚拟化。另外,为什么智能指针类不完全存储指针而是存储值。这不应该是 T* obj 吗?除此之外,按照 JS 的建议去做应该/将会起作用。如果它没有使用新代码进行更新,并且在您进行这些更改后会出现新错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多