将链接器错误作为已定义的运算符

getting a linker error as already defined operator

本文关键字:定义 运算符 链接 错误      更新时间:2023-10-16

我看到链接器错误,需要您的帮助。我有一个X.dll,其中有一个名为DBFieldBase的类。在我的工作空间X中,我正在为一些与数据库相关的应用程序使用vector。我使用的载体来自第三方ospace。现在我正试图在另一个工作空间Y中使用vector。我在visualstudio2010中的linker->input选项中添加了相应的include文件和.lib文件。我为工作空间X做了dllexport,为了在Y中使用它,我使用的是dllimport。我得到的错误在下面给出

X.lib(X.dll):错误LNK2005:"public:类DBFieldBase*&__thiscall vector::operator[](unsigned int)"(??A$vector@PAVDBFieldBase@@@@QAEAAPAVDBFieldBase@@I@Z)在sdb.obj 中定义

我不知道到底是什么原因导致了这个错误。同样的代码在VS6.0中成功编译,现在我正试图在VS2010中构建它。如果我遗漏了什么,请告诉我。提前谢谢。

附言:我试着在互联网上搜索类似问题的解决方案,但不幸的是没有成功。

来自第三方的矢量代码如下:

class os_vector
{
public:
typedef T                        value_type;
typedef OS_REFERENCE( T )        reference;
typedef OS_CONST_REFERENCE( T )  const_reference;
typedef OS_SIZE_TYPE( T )        size_type;
typedef OS_DIFF_TYPE( T )        difference_type;
typedef OS_ALLOCATOR( T )        allocator_type;
typedef T*        pointer;
typedef const T*  const_pointer;
typedef T*        iterator;
typedef const T*  const_iterator;
typedef os_reverse_iterator
  <
  T*,
  T,
  OS_REFERENCE( T ),
  T*,
  OS_DIFF_TYPE( T )
  >  reverse_iterator;
typedef os_reverse_iterator
  <
  const T*,
  T,
  OS_CONST_REFERENCE( T ),
  const T*,
  OS_DIFF_TYPE( T )
  >  const_reverse_iterator;
// Construct me to be an empty vector.
os_vector() :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_()
  {
  }
// Construct me to be an empty vector.
explicit os_vector( const OS_ALLOCATOR( T ) & alloc ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  }
// Construct me to contain `n` ( >0 ) elements. Each element will be
// a copy of `value`.
os_vector
  (
  size_type n,
  const T& value, // = T()
  const OS_ALLOCATOR( T ) & alloc // = OS_ALLOCATOR( T )()
  ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  assign( n, value );
  }
os_vector ( size_type n, const T& value ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_()
  {
  assign( n, value );
  }
os_vector ( size_type n ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_()
  {
  assign( n, T() );
  }

// Construct me to contain copies of all the elements in `original`.
os_vector( const os_vector OS_ALLOCATE_ARG_2( T, Allocator ) & original ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( original.get_allocator() )
  {
  assign( original.begin(), original.end() );
  }
// Construct me to contain all of the elements in the
// range [`first`, `last`).
  template< class InIt >
  os_vector
    (
    InIt first,
    InIt last,
    const OS_ALLOCATOR( T ) & alloc = OS_ALLOCATOR( T )()
    ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  assign( first, last );
  }
// Destroy me.
~os_vector()
  {
  clear();
  }
// Replace my contents with a copy of the elements in `original`,
// resizing if necessary.
os_vector OS_ALLOCATE_ARG_2( T, Allocator ) & operator=
  (
  const os_vector OS_ALLOCATE_ARG_2( T, Allocator ) & original
  );
// Remove all my current elements, and then insert the elements
// in range [`first`, `last`).
void assign( const_iterator first, const_iterator last )
  {
  if ( first == begin() )
    erase( begin() + ( last - first ), end() );
  else
    assign_aux( first, last );
  }

  // Remove all my current elements, and then insert the elements
  // in range [`first`, `last`).
  template< class InIt >
  void assign( InIt first, InIt last )
    {
    assign_aux( first, last );
    }

// Remove all my current elements, and then insert `n` copies of
// `value`.
void assign( size_type n, const T& value );

  void assign( size_type n )
    {
    assign( n, T() );
    }

// Return a copy of the allocator I am using.
allocator_type get_allocator() const
  {
  return alloc_;
  }
// Return a random access iterator positioned at my first element.
iterator begin()
  {
  return start_;
  }
// Return a constant random access iterator positioned at my first
// element.
const_iterator begin() const
  {
  return start_;
  }
// Return a random access iterator positioned immediately after my
// last element.
iterator end()
  {
  return finish_;
  }
// Return a constant random access iterator positioned immediately after
// my last element.
const_iterator end() const
  {
  return finish_;
  }
// Return a random access reverse iterator positioned immediately after
// my last element.
reverse_iterator rbegin()
  {
  return reverse_iterator( end() );
  }
// Return a constant random access reverse iterator positioned
// immediately after my last element.
const_reverse_iterator rbegin() const
  {
  return const_reverse_iterator( end() );
  }
// Return a random access reverse iterator positioned at my first
// element.
reverse_iterator rend()
  {
  return reverse_iterator( begin() );
  }
// Return a constant random access reverse iterator positioned at my
// first element.
const_reverse_iterator rend() const
  {
  return const_reverse_iterator( begin() );
  }
// Return the number of elements that I contain.
size_type size() const
  {
  return end() - begin();
  }
// Return the maximum number of elements that I can contain.
size_type max_size() const
  {
  return alloc_.max_size();
  }
// Cause myself to hold `n` elements, using `value` to expand
// myself if necessary.
void resize( size_type n, T value )
  {
  if ( n > size() )
    insert( end(), n - size(), value );
  else
    erase( begin() + n, end() );
  }
// Cause myself to hold `n` elements using the default constructor
// to expand myself if necessary.
void resize( size_type n )
  {
  resize( n, T() );
  }
// Return the number of elements that I can contain without allocating
// more memory.
size_type capacity() const
  {
  return end_of_storage_ - start_;
  }
// Return true if I contain no elements.
bool empty() const
  {
  return begin() == end();
  }
// Change my capacity to be at least `n`.  Does not affect my
// current size.
void reserve( size_type n );
// Return a reference to my `n`th element.
reference operator[]( size_type n )
  {
  OS_ASSERT_NOT_EMPTY( empty() )
  OS_ASSERT_INDEX_OK( n, 0, size() - 1 )
  return *( begin() + n );
  }
// Return a constant reference to my `n`th element.
const_reference operator[]( size_type n ) const
  {
  OS_ASSERT_NOT_EMPTY( empty() )
  OS_ASSERT_INDEX_OK( n, 0, size() - 1 )
  return *( begin() + n );
  }
// Return a reference to my `n`th element.
reference at( size_type n )
  {
  if ( n >= size() )
    os_throw_out_of_range();
  return *( begin() + n );
  }
// Return a constant reference to my `n`th element.
const_reference at( size_type n ) const
  {
  if ( n >= size() )
    os_throw_out_of_range();
  return *( begin() + n );
  }
// Return a reference to my first element.
reference front()
  {
  OS_ASSERT_NOT_EMPTY( empty() )
  return *begin();
  }
// Return a constant reference to my first element.
const_reference front() const
  {
  OS_ASSERT_NOT_EMPTY( empty() )
  return *begin();
  }
// Return a reference to my last element.
reference back()
  {
  OS_ASSERT_NOT_EMPTY( empty() )
  return *( end() - 1 );
  }
// Return a constant reference to my last element.
const_reference back() const
  {
  OS_ASSERT_NOT_EMPTY( empty() )
  return *( end() - 1 );
  }
// Add `value` at my end.
void push_back( const_reference value )
  {
  if ( finish_ != end_of_storage_ )
    {
    alloc_.construct( finish_, value );
    ++finish_;
    }
  else
    insert_aux( end(), value );
  }
// Erase my last element.
void pop_back()
  {
  OS_ASSERT_NOT_EMPTY_ELSE( empty() )
    {
    --finish_; // not on a single line due to Borland problem
    alloc_.destroy( finish_ );
    }
  }
// Insert `value` at `pos` and return an iterator pointing to the new
// element's position.
iterator insert( iterator pos, const T& value )
  {
  size_type n = pos - begin();
  if ( finish_ != end_of_storage_ && pos == finish_ )
    {
    alloc_.construct( finish_, value );
    ++finish_;
    }
  else
    insert_aux( pos, value );
  return begin() + n;
  }
// Insert an element constructed with the default constructor at `pos` and
// return an iterator pointing to the new element's position.
// not standard, left for backward compatibility
 iterator insert( iterator pos )
   {
   return insert( pos, T() );
   }

// Insert `n` copies of `value` at `pos`.
void insert( iterator pos, size_type n, const T& value );
// Insert copies of the elements in range [`first`, `last`) at `pos`.
  template< class InIt >
  void insert( iterator pos, InIt first, InIt last );

// Erase the element at `pos`.
iterator erase( iterator pos )
  {
  if ( !( pos + 1 == end() ) )
    copy( pos + 1, end(), pos );
  pop_back();
  return pos;
  }
// Erase the elements in range [`first`, `last`).
iterator erase( iterator first, iterator last )
  {
  iterator i = copy( last, end(), first );
  destroy( i, finish_, alloc_ );
  finish_ = finish_ - ( last - first );
  return first;
  }
// Swap my contents with those of `original`.
void swap( os_vector OS_ALLOCATE_ARG_2( T, Allocator ) & original )
  {
  if ( !(alloc_ == original.alloc_ ) )
    {
    os_vector OS_ALLOCATE_ARG_2( T, Allocator ) tmp( *this );
    assign( original.begin(), original.end() );
    original.assign( tmp.begin(), tmp.end() );
    }
  else
    {
      ::swap( start_, original.start_ );
      ::swap( finish_, original.finish_ );
      ::swap( end_of_storage_, original.end_of_storage_ );
      ::swap( alloc_, original.alloc_ );
    }
  }
// Erase all of my elements.
void clear()
  {
  if ( start_ )
    {
    destroy( start_, finish_, alloc_ );
    alloc_.deallocate( start_ );
    }
  start_ = finish_ = end_of_storage_ = 0;
  }
protected:
void insert_aux( T* pos, const T& value );

  template< class InIt >
  void assign_aux( InIt first, InIt last );

private:
// Data members.
iterator start_;
iterator finish_;
iterator end_of_storage_;
allocator_type alloc_;

public:
// Construct me to contain n ( >0 ) elements. Each element will be
// default constructed.
// This remains for compatibility.  It will be removed in a future release.
os_vector
  (
  const OS_ALLOCATOR( T ) & alloc,
  size_type n
  ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  assign( n, T() );
  }
// Construct me to contain n ( >0 ) elements. Each element will be
// a copy of `value`.
// This remains for compatibility.  It will be removed in a future release.
os_vector
  (
  const OS_ALLOCATOR( T ) & alloc,
  size_type n,
  const T& value
  ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  assign( n, value );
  }
// Construct me to contain copies of all the elements in `original`.
// This remains for compatibility.  It will be removed in a future release.
os_vector
  (
  const OS_ALLOCATOR( T ) & alloc,
  const os_vector OS_ALLOCATE_ARG_2( T, Allocator ) & original
  ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  assign( original.begin(), original.end() );
  }
// Construct me to contain all of the elements in the
// range [`first`, `last`).
// This remains for compatibility.  It will be removed in a future release.
os_vector
  (
  const OS_ALLOCATOR( T ) & alloc,
  const_iterator first,
  const_iterator last
  ) :
  start_( 0 ),
  finish_( 0 ),
  end_of_storage_( 0 ),
  alloc_( alloc )
  {
  assign( first, last );
  }
// Erase all of my elements.
// This remains for compatibility.  It will be removed in a future release.
void erase()
  {
  clear();
  }
};

在X.DLL中,我有一个类DBFieldBase,它类似于我们的普通类,包含成员变量和函数。

在Y工作空间中的一个类中,我使用的向量的用法如下:

private:
vector < DBFieldBase *> &       GetASDVect (void);
vector <DBFieldBase *>          m_ASDVect;

然后在类外的同一个头文件中有GetASDect的定义。其内联

inline vector <DBFieldBase *> & ASD_sdb::GetASDVect (void)
{
return this->m_ASDVect; 
}

如果你还需要我的帮助,请告诉我。

您已经多次定义了一个符号。我想X.dll和Y.dll中都定义了符号?