这是一个Group类,类似于Vector。我可以创建一个组的矢量,并且工作正常。我在创建群组时遇到了困难。此代码编译并运行,但组的行为与组向量的行为不同 - 请参阅输出。我觉得我在Group中缺少一个处理模板类型的特殊构造函数?也许它是别的东西 - 任何指针都感激不尽。
#include <vector>
template <class T>
class Group
{
private:
T *data;
int current_size;
int max_size;
private:
void expand();
public:
Group();
Group(int size);
~Group();
T operator[](int index) const;
int count() const;
int add_item(const T new_item);
};
template <class T>
Group<T>::Group()
{
data = NULL;
max_size = 0;
current_size = 0;
}
template <class T>
Group<T>::Group(int size)
{
if (size < 2)
size = 2;
data = new T[size];
max_size = size;
current_size = 0;
}
template <class T>
Group<T>::~Group()
{
if (data != NULL)
delete[] data;
current_size = 0;
max_size = 0;
}
template <class T>
void Group<T>::expand()
{
if (data == NULL)
{
current_size = 0;
max_size = 2;
data = new T[2];
}
else
{
// printf("expanding %x from %d to %d\n", this, current_size, current_size*2);
T *tempArray = new T[max_size * 2];
for (int i = 0; i < max_size; i++)
{
tempArray[i] = data[i];
}
delete[] data;
data = tempArray;
max_size = max_size * 2;
}
}
template <class T>
int Group<T>::add_item(const T new_item)
{
// expand the array if necessary
while (current_size >= (max_size))
expand();
// add_item the new thing
data[current_size] = new_item;
current_size++;
return (current_size);
}
template <class T>
inline T Group<T>::operator[](int index) const
{
return data[index];
}
template <class T>
inline int Group<T>::count() const
{
return current_size;
}
int main()
{
// Vector of Groups works fine
int numgroups = 3; // just 3 groups for testing
// a vector of Groups
std::vector<Group<int>> setofgroups(numgroups);
printf("setofgroups count=%d\n", setofgroups.size());
// some test data
// 4 items in first group
setofgroups[0].add_item(6);
setofgroups[0].add_item(9);
setofgroups[0].add_item(15);
setofgroups[0].add_item(18);
// one item in second
setofgroups[1].add_item(7);
// two items in third
setofgroups[2].add_item(8);
setofgroups[2].add_item(25);
// for each group, print the member values
for (int g = 0; g < setofgroups.size(); g++)
{
printf("group %d\n", g);
for (int i = 0; i < setofgroups[g].count(); i++)
printf(" member %d, value %d\n", i, setofgroups[g][i]);
}
// Group of groups doesn't seem to work
Group<Group<int>> groupofgroups(numgroups);
// this returns ZERO - not 3 as I expected
printf("groupofgroups count=%d\n", groupofgroups.count());
groupofgroups[0].add_item(6);
groupofgroups[0].add_item(9);
groupofgroups[0].add_item(15);
groupofgroups[0].add_item(18);
printf("groupofgroups[0].count=%d\n", groupofgroups[0].count()); // this returns ZERO - where did the items go?
groupofgroups[1].add_item(7);
// two items in third
groupofgroups[2].add_item(8);
groupofgroups[2].add_item(25);
// for each group, print the member values
for (int g = 0; g < groupofgroups.count(); g++)
{
printf("group 2 %d (count=%d)\n", g, groupofgroups[g].count());
for (int i = 0; i < groupofgroups[g].count(); i++)
printf(" member %d, value %d\n", i, groupofgroups[g][i]);
}
return 0;
}
输出:
setofgroups count=3
group 0
member 0, value 6
member 1, value 9
member 2, value 15
member 3, value 18
group 1
member 0, value 7
group 2
member 0, value 8
member 1, value 25
groupofgroups count=0
groupofgroups[0].count=0
答案 0 :(得分:0)
有两件事需要解决:
operator[]
一起返回引用,否则所有修改都将应用于元素的临时副本答案 1 :(得分:0)
你班上有一个非平凡的析构函数。这意味着默认的复制构造函数和默认的复制赋值将会出错。
这是一个简单的例子:
Group<int> a(4); // ok, ready to add some elements in the freshly allocated a.data
a.add_item(1);
int count = a.add_item(2); // ok a contains 2 items 1 and 2
if (count == 2) {
Group<int> b = a; // the default copy ctor make b.data == a.data...
std::cout << "b contains " << b.count() << " items" << std::endl; // nice up to here
} // horror: b reaches end of life and destructor calls delete[](b.data) !
// a.data is now a dangling pointer...
所以你必须实现复制构造函数和复制赋值运算符,或者将它们标记为明确删除 - 这是3的规则(更多细节here)
如果您不实现它们,编译器将隐含地提供移动ctor和移动赋值运算符,它不会比复制版本工作得多。因此,您必须实现它们或将它们标记为明确删除 - 这是5的规则。
容器的推荐operator []
- 标准库使用的是:
T& operator[] (size_t index); // used for a[i] = ...
const T& operator[] (size_t index) const; // used for x = a[i];
使用引用可以避免不必要的大对象副本......