将链接器错误作为已定义的运算符
getting a linker error as already defined operator
我看到链接器错误,需要您的帮助。我有一个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中都定义了符号?
相关文章:
- 在 C++ 的自定义运算符中删除与删除[](不同于常见的删除与删除[]问题)
- 自定义运算符重载C++,无开销
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 如何使用C++将MXNET自定义运算符构建到单独的库/包中?
- 模板类的用户定义运算符上的 C++ 隐式转换
- 什么是编程语言支持定义您自己的自定义运算符?
- 如何在Qt中为矩阵类定义[ ][ ]运算符?
- 在 c++ 迭代器中,我应该同时定义运算符== 和运算符!=吗?
- 在 rxcpp 中创建自定义运算符
- 错误 C2676;在C++的二叉搜索树类中定义 ++ 运算符时遇到问题
- std::map :使用自定义运算符时更新密钥
- 最初定义运算符C++在哪里
- 如何在Tensorflow Lite中添加自定义运算符
- 如何在 rxcpp 自定义运算符中正确推断泛型
- 在模板化类之外定义运算符重载
- 为类定义之外的模板类定义运算符[]()(数组订阅)
- 是否可以在类定义之外定义运算符[]()(数组订阅)
- C++ 重新定义运算符<() 和运算符!=()
- 如何将上下文信息传递给自定义运算符<<适用于 std::iostream
- 无法在C++中定义++运算符,这里有什么问题?