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