这是一个奇怪的。请注意,这是减少示例代码,并故意错过析构函数。)
template <class f, class g> class Ptr;
class RealBase
{
};
template <class a, class b, class c = Ptr<a,b> >
class Base : public RealBase
{
public:
Base(){};
};
template <class d, class e>
class Derived : public Base <d,e>
{
public:
Derived(){};
void DerivedMethod(){};
};
typedef Derived<double,double> D_Derived;
template <class f, class g>
class Ptr
{
public:
Ptr(){};
Ptr(Base<f,g,Ptr<f,g> >* a){in = a;};
Base<f,g,Ptr<f,g> >* operator->()
{
return in;
};
Base<f,g,Ptr<f,g> >& operator*()
{
return *in;
};
private:
Base<f,g,Ptr<f,g> >* in;
};
我在向量中使用此示例中的Ptr类,作为指向Derived类的指针。
正如我们所看到的,Ptr采用Base<>*
作为构造函数参数。
不幸的是我需要一个带有const Base&lt;&gt; *的构造函数,我不能简单地这样做:
Ptr(const Base<>* a) { in = const_cast<Base<>*>(a)};
我怎么能让这个类接受const Base<>*
作为它的构造函数?
编辑:
好的,事实证明我可以通过更改不相关的代码来解决这个问题,所以现在它有点像一个问题=]我花了一天时间来解决这个问题= [
答案 0 :(得分:2)
我认为您需要定义一个单独的类来包装指向const的指针,因为不仅构造函数的参数,而且运算符的返回类型也应该更改为const版本。如果您将ConstPtr
friend
Ptr
设为template<...>
class ConstPtr {
const Base<...> *in;
ConstPtr(Base<...>* a) { in = a; }
ConstPtr(const Base<...>* a) { in = a; }
ConstPtr(const Ptr<...> &a) { in = a.in; }
...
};
,那么这应该非常合理:
template<..., class P>
P make_ptr(Base<...> *t);
template<...>
Ptr<...> make_ptr< ..., Ptr<...> >(Base<...> *t) {
return Ptr(t);
}
template<...>
ConstPtr<...> make_ptr< ..., ConstPtr<...> >(const Base<...> *t) {
return ConstPtr(t)
}
要从原始指针构造包装器,您可以添加一个重载函数,或多或少像这样:
{{1}}
答案 1 :(得分:1)
您的Ptr
类有一个非const指针成员。没有一些不安全的演员表,您将无法指定const Base*
。你想要那个吗?试试这个:
template <class f, class g>
class Ptr
{
public:
Ptr(){};
Ptr(Base<f,g,Ptr<f,g> > const* a) { in = *a; }
Base<f,g,Ptr<f,g> >* operator->()
{
return ∈
};
Base<f,g,Ptr<f,g> >& operator*()
{
return in;
};
private:
Base<f,g,Ptr<f,g> > in;
};
答案 2 :(得分:1)
根据你的例子你应该做
Ptr( const Base< f,g, Ptr< f, g > >* a )
{
in = const_cast< Base<f,g,Ptr<f,g> >* > ( a );
}
ps:我不喜欢const_cast,在类似情况下我试图避免这种情况。也许需要为const和非const参数做两次Ptr实现。