使用模板参数时的交叉引用

时间:2014-12-24 23:52:37

标签: c++ class templates cross-reference

我通常知道如何处理交叉引用,但在这里我被卡住了。

设一个智能指针类:

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());
    }
};

1 个答案:

答案 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关键字来定义课外发生的定义。