我通常知道如何处理交叉引用,但在这里我被卡住了。
设一个智能指针类:
template< typename T >
SharedPointer
{
T * _ptr;
};
并且:
class Array;
class Value
{
SharedPointer< Array > _pa;
};
并且:
class Array
{
Value someFunc();
}
这里我在SharedPointer类中有警告说我删除了指向不完整类型对象的指针,我猜这是由于前向声明。
Warning 2 warning C4150: deletion of pointer to incomplete type 'script::Array'; no destructor called c:\XXXXX\SharedPointer.h 77
我该怎么做才能解决这个问题?我看到的唯一解决方案是将整个SharedPointer类重写为:
template< typename pT >
SharedPointer
{
pT _ptr;
};
使用它代替:
SharedPointer< Array * >
如果可能的话,我想避免重写这个课程。还有其他解决方案吗? 谢谢:))
编辑:这是真正的源代码:
class Value
{
PUBLIC enum type_e
{
E_NULL,
E_INT,
E_FLOAT,
E_STRING,
E_ARRAY,
E_MAP,
E_FUNCTION,
E_REFERENCE // TODO For functions like fn( scalar & val )
};
PRIVATE union
{
int _i;
float _f;
std::string * _ps;
IFunction * _pf;
};
PRIVATE SharedPointer< Array > _pa;
PRIVATE SharedPointer< Map > _pm;
PRIVATE SharedPointer< Value > _ref;
PRIVATE type_e _type;
PUBLIC Value();
PUBLIC Value( bool b );
PUBLIC Value( int i );
PUBLIC Value( float f );
PUBLIC Value( const std::string & s );
PUBLIC Value( SharedPointer< Array > pa );
PUBLIC Value( SharedPointer< Map > pm );
PUBLIC Value( IFunction * pf );
PUBLIC Value( SharedPointer< Value > ref );
PUBLIC Value( const Value & v );
PUBLIC ~Value() { }
PUBLIC Value operator + ( const Value & v ) const;
PUBLIC Value operator - ( const Value & v ) const;
PUBLIC Value operator * ( const Value & v ) const;
PUBLIC Value operator / ( const Value & v ) const;
PUBLIC Value operator % ( const Value & v ) const;
PUBLIC Value operator ^ ( const Value & v ) const;
PUBLIC Value operator << ( const Value & v ) const;
PUBLIC Value operator - () const;
PUBLIC Value operator && ( const Value & v ) const;
PUBLIC Value operator || ( const Value & v ) const;
PUBLIC Value xor( const Value & v ) const;
PUBLIC Value operator ! () const;
PUBLIC Value & operator = ( const Value & v );
PUBLIC Value operator () ( Scope & scope, const std::vector< Value > & args ) const;
PUBLIC Value & getRef( const Value & v ) const;
PUBLIC Value getCpy( const Value & v ) const;
PUBLIC inline type_e getType() const throw() { return _type; }
PUBLIC inline bool isNull() const throw() { return E_NULL == _type; }
PUBLIC inline bool isInt() const throw() { return E_INT == _type; }
PUBLIC inline bool isFloat() const throw() { return E_FLOAT == _type; }
PUBLIC inline bool isString() const throw() { return E_STRING == _type; }
PUBLIC inline bool isArray() const throw() { return E_ARRAY == _type; }
PUBLIC inline bool isMap() const throw() { return E_MAP == _type; }
PUBLIC inline bool isFunction() const throw() { return E_FUNCTION == _type; }
PUBLIC inline bool isReference() const throw() { return E_REFERENCE == _type; }
PUBLIC inline bool isNumeric() const throw() { return E_INT == _type || E_FLOAT == _type; }
PUBLIC type_e toNumeric( int & asInt, float & asFloat ) const;
PUBLIC std::string toString() const;
PUBLIC operator bool () const throw();
};
class Array
{
PRIVATE std::vector< Value > _items;
PUBLIC Array( const std::vector< Value > & items );
PUBLIC ~Array();
PUBLIC Value & getRef( int index );
PUBLIC Value getCpy( int index ) const;
PUBLIC int getSize() const;
};
template< typename T >
class SharedPointer
{
template< typename U >
friend class SharedPointer;
PRIVATE T * p;
PRIVATE size_t * c;
PUBLIC SharedPointer()
: p()
, c() { }
PUBLIC explicit SharedPointer( T * s )
: p( s )
, c( new size_t( 1 ) ) { }
PUBLIC SharedPointer( const SharedPointer & s )
: p( s.p )
, c( s.c )
{
if( this->c )
{
++*(this->c);
}
}
PUBLIC SharedPointer & operator = ( const SharedPointer & s )
{
if( this != & s )
{
this->clear();
this->p = s.p;
this->c = s.c;
if( this->c )
{
++*(this->c);
}
}
return *this;
}
PUBLIC template< typename U >
SharedPointer( const SharedPointer< U > & s )
: p( s.p )
, c( s.c )
{
if( c )
{
++*(this->c);
}
}
PUBLIC ~SharedPointer()
{
this->clear();
}
PUBLIC void clear()
{
if( this->c )
{
if( *(this->c) == 1 )
{
delete this->p;
}
if( ! --*(this->c) )
{
delete this->c;
}
}
this->c = NULL;
this->p = NULL;
}
PUBLIC T * get() const
{
return this->c ? this->p : NULL;
}
PUBLIC T * operator -> () const
{
return this->get();
}
PUBLIC T & operator * () const
{
return *(this->get());
}
};
答案 0 :(得分:2)
问题在于,由于Value
没有析构函数,因此会为您创建默认析构函数。由于它最终被内联定义,因此在类定义中,您最终会删除不完整的类型。换句话说,就好像你已经在头文件中写了这个:
class Value
{
SharedPointer< Array > _pa;
~Value() { //This will end up calling the destructor for `_pa`. To do that, if needs `Array` to be a completely defined type. }
};
使析构函数显式化并将其移动到cpp文件。请注意,您也可以use the default
关键字来定义课外发生的定义。