【问题标题】:Object declaring c++对象声明 c++
【发布时间】:2012-02-18 22:37:19
【问题描述】:

应要求我已经发布了code in idone.com的其余部分

所以我必须创建自己的 Vector 类,我做到了。这是必需的。 然而,当我在另一个类中实现它时,它给了我these errors 这就是我尝试实现它的方式:

#include "Vector.h"

class UserDB
{
private:
    Vector<AccountInfo*> _accounts;
//more code that previous to this implementation worked fine.
};

我希望有人能告诉我该怎么做。我对这个完全一无所知。 Java从来没有给出过这样的错误,无论如何...... 编辑:我也意识到,当我说Vector&lt;int&gt; _accounts; 之类的东西时,它运行得很好,但是当使用诸如 Vector 之类的类时,似乎几乎不可能修复它。我读了很多书,但我似乎仍然找不到解决这个问题的方法。

这是我的矢量标题

#include "ArrayClass.h" //Class with more methods
#include "AbstractVector.h" //Another class with more method
template <class DT>
class Vector: virtual public ArrayClass<DT>,
virtual public AbstractVector<DT>
{
protected:
int _currSize;
int _incFactor;
public:
Vector ();
Vector (int n);
Vector (int n, DT& val);
Vector (const Vector<DT>& v);
Vector (const ArrayClass<DT>& ac);
virtual ~Vector();
void operator= (const Vector<DT>& v);
void operator= (const ArrayClass<DT>& ac);
virtual void insert (const DT& item, int index);
virtual void remove (int index);
virtual void add (const DT& item);
virtual int size() const;
virtual int capacity() const;
virtual int incFactor() const;
virtual void setIncFactor(int f);
void setCapacity(int c);
};

而这个是实际代码Vector.cpp

#include "Vector.h"

template <class DT>
Vector<DT>::Vector () : ArrayClass<DT>()
{
    _currSize = 0;
    _incFactor = 5;
}
Vector<DT>::~Vector ()
{
_currSize = NULL;
_incFactor = NULL;
}
template <class DT>
Vector<DT>::Vector (int n): ArrayClass<DT>(n)
{
    _currSize = 0;
    _incFactor = (n+1)/2;
}
template <class DT>
Vector<DT>::Vector (int n, DT& val)
    : ArrayClass<DT>(n, val)
{
    _currSize = 0;
    _incFactor = n/2;
}
template <class DT>
Vector<DT>::Vector (const Vector<DT>&v)
    : ArrayClass<DT> (v)
{
    _currSize = v._currSize;
    _incFactor = v.incFactor();
}
template <class DT>
Vector<DT>::Vector (const ArrayClass<DT>& ac)
    : ArrayClass<DT> (ac)
{
    _currSize = ac.size();
    _incFactor = (_currSize+1)/2;
}
template <class DT>
void Vector<DT>::operator= (const Vector<DT>& v)
{
    ArrayClass<DT>::copy (v);
    _currSize = v._currSize;
    _incFactor = v.incFactor();
}
//template <class DT>
//void Vector<DT>::operator= (const ArrayClass<DT>&ac)
//{
//  ArrayClass<DT>::copy (ac);
//  _currSize = ac.size();
//  _incFactor = (_currSize+1)/2;
//}
template <class DT>
int Vector<DT>::size() const
{
    return _currSize;
}
template <class DT>
int Vector<DT>::capacity() const
{
    return _size;
}
template <class DT>
int Vector<DT>::incFactor() const
{
    return _incFactor;
}
template <class DT>
void Vector<DT>::add (const DT& item)
{
    insert (item, _currSize);
}
template <class DT>
void Vector<DT>::setIncFactor(int f)
{
    if (f >= 0) _incFactor = f;
}
template <class DT>
void Vector<DT>::setCapacity(int c)
{
    int len = _currSize;
    if (len > c) len = c;
    DT* paNew = new DT[c];
    if (paNew == NULL)
    {
        throw ArrayMemoryException();
    }
    for (int i = 0; i < len; i++)
    {
        paNew[i] = paObject[i];
    }
    if (paObject != NULL)
    {
        delete[] paObject;
    }
    paObject = paNew;
    _size = c;
    if (_currSize > len)
    {
        _currSize = len;
    }
}
template <class DT>
void Vector<DT>::insert (const DT& item, int index)
{
if ((index < 0) || (index > _currSize))
{
throw ArrayBoundsException();
}
if (_currSize+1 == _size)
{
setCapacity (_size + _incFactor);
}
_currSize++;
for (int i = _currSize-1; i > index; i--)
{
(*this)[i] = (*this)[i-1];
}
(*this)[index] = item;
}
template <class DT>
void Vector<DT>::remove (int index)
{
if ((index < 0) || (index >= _currSize))
{
throw ArrayBoundsException();
}
if (_currSize <= _size-_incFactor)
{
setCapacity (_size - _incFactor);
}
for (int i = index; i < _currSize-1; i++)
{
(*this)[i] = (*this)[i+1];
}
_currSize--;
}

【问题讨论】:

  • 让我猜猜,你把你的vectors成员函数的定义放在一个.cxx文件里?
  • 你在Vector.h有什么?
  • 发布您的 Vector.h 和 Vector.cpp 文件,或者至少发布每个文件的前 20-30 行。
  • @PlasmaHH:更像是链接中不包含 cpp...
  • 在模板被实例化的那一刻,模板定义应该在范围内。因为编译器使用该定义来生成一个新类(具有给定的模板参数)。因此,这意味着模板应该在头文件中定义。

标签: c++


【解决方案1】:

在编译您的代码时,在模板被实例化的地方,即在您的代码中

Vector<AccountInfo*> _accounts;

编译器将使用模板Vector(带有给定的模板参数,即AccountInfo*)生成一个新类。因此编译器此时需要访问模板Vector&lt;T&gt;的实现。

因此,这意味着模板Vector&lt;T&gt; 应该完全在头文件中实现。

如果您确实想保持模板定义和实现之间的分离,那么
你可以有两个头文件,一个Vector.h和另一个Vector_impl.h,Vector_impl.h包含模板的实现。

将Vector.h 包含在Vector_impl.h 中,并将Vector_impl.h 包含在您要实例化模板的.cpp 文件中,即Vector &lt; AccountInfo*&gt;.

【讨论】:

  • 我有点困惑。我究竟应该“实施”解决问题的“模板Vector”怎么样?你的意思是把Vector.cpp的内容放到Vector.h里面吗?
  • @Yokhen,你应该明白,一个模板只用于生成其他类。如果未使用模板,即未在代码中的任何位置实例化,则不会为该模板生成任何代码。因此,模板实现应该在您实例化它的文件中“#included”。
  • 所以,刚刚删除了 Vector.cpp 文件并将其内容添加到 Vector.h,我得到了同样的错误 with different content...
  • @Yokhen : 你确定 ArrayClass 的构造函数也被定义了吗?
  • @Yokhen 如果可能发布 ArrayClass.h 和 Abstractvector.h 或任何其他文件,我们可能需要编译您的代码。您可以使用codepad.org 或pastebin.com 或ideone.com
【解决方案2】:

出现这些错误是因为链接阶段(发生在编译阶段之后)找不到 Vector 的构造函数和析构函数以及 ArrayClass 的析构函数的二进制代码。

我的猜测是您忘记在模板类中定义这些函数,但您声明了它们。它之前编译过,因为您实际上并没有实例化该类的对象(我的猜测)。简单的解决方案(假设我的猜测是正确的)是将方法定义与声明放在同一个文件中(即 Vector.h)。你能显示“Vector.h”中的内容吗?

最后一句话:这里的“private”关键字没用,类默认是私有的。

编辑: 为了扩展我的评论,您的代码实际上缺少Vector::~Vector 的定义。 Java 没有抱怨它,因为那里不存在析构函数 :)

【讨论】:

  • 关于你的最后一句话:露骨很少是坏事。
  • 不过我并不完全满意。我想不出第一个错误出现的原因。
  • 第一个错误是因为Vector&lt;class AccountInfo*&gt;::Vector&lt;class AccountInfo*&gt;(void)构造函数没有在任何翻译单元中实例化,因此无法链接符号。它没有被实例化,因为没有 TU 同时具有模板函数定义,和要实例化的类型,因为模板函数定义在它自己的 cpp 文件中。
  • 所以我前段时间添加了一个析构函数,问题仍然存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 2018-06-17
  • 1970-01-01
相关资源
最近更新 更多