创建一个类objs数组

时间:2009-01-17 04:02:07

标签: c++

考虑以下课程

class test
{
public:
test(int x){ cout<< "test \n"; }

};

现在我想创建50个类test对象的数组。我无法改变课堂测试。

可以在堆或堆栈上创建对象。

在这种情况下,无法在堆栈上创建objs,因为我们在类

中没有默认构造函数
test objs(1)[50]; /// Error...

现在我们可以考虑在这样的堆上创建obj ..

test ** objs = NULL;
objs = (test **) malloc( 50 * sizeof (test *));
for (int i =0; i<50 ; ++ i)
{
   objs[i] = new test(1);
}

我不想使用malloc。还有其他方法吗?

如果你们想到更多解决方案,请发布它们......

6 个答案:

答案 0 :(得分:7)

如果没有默认构造函数,则无法创建对象数组,如 Foo foo [N] 。这是语言规范的一部分。

执行:

test * objs [50];
for() objs[i] = new test(1).

您不需要malloc()。你可以声明一个指针数组。

c++decl> explain int * objs [50]
declare objs as array 50 of pointer to int

但你可能应该附加某种自动RAII型破坏。


公开

OR 子类测试

class TempTest : public test
{
public:
  TempTest() : test(1) {}
  TempTest(int x) : test(x) {}
  TempTest(const     test & theTest ) : test(theTest) {}
  TempTest(const TempTest & theTest ) : test(theTest) {}
  test & operator=( const     test & theTest ) { return test::operator=(theTest); }
  test & operator=( const TempTest & theTest ) { return test::operator=(theTest); }
  virtual ~TempTest() {}
};

然后:

TempTest  array[50];

您可以将每个 TempTest 对象视为 test 对象。

注意:operator =()&amp;复制构造函数不是继承的,因此必要时重新指定。

答案 1 :(得分:4)

为什么需要数组?

std::vector<test*> v(50);

或评论中建议的@j_random_hacker

std::vector<test> v(50, test(1));

一个例子:

/** g++ -Wall -o vector_test *.cpp && vector_test */
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

struct Test {
  int value;
  Test(int x) : value(x) 
  {
    std::cout << "Test(" << value << ")" << " ";
  }
  operator int() const
  {
    std::cout << "int(" << value << ")" << " ";
    return value;
  }
};

int main()
{
  using namespace std;

  vector<Test> v(5, Test(1));

  cout << endl;
  copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
  cout << endl;

  v[1] = 2;
  v[2].value = 3;

  cout << endl;
  copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
  cout << endl;

  return 0;
}

输出:

Test(1) 
int(1) 1 int(1) 1 int(1) 1 int(1) 1 int(1) 1 
Test(2) 
int(1) 1 int(2) 2 int(3) 3 int(1) 1 int(1) 1 

答案 2 :(得分:3)

与许多人认为的相反,您实际上可以创建一个没有默认构造函数的对象数组。你不能做的是让它为所有构造函数的invokations使用一组参数。你只需要初始化它的所有元素。也就是说,您可以执行以下操作:

#define PRINTT(z, n, initializer) initializer
test objs[50] = {
    BOOST_PP_ENUM(50, PRINTT, 1) // yields 1, 1, 1, .... 1
};
#undef PRINTT

这将使用1初始化所有50个元素。boost::pp用于自动连续50次打印1

答案 3 :(得分:2)

我认为其他响应者也在字面上对待这个问题。

如果您真正想做的就是创建一个由50个对象组成的“组”,您可以将其视为一个数组,那么到目前为止,最简单,最易维护的方法是完成您要做的事情:

std::vector<test> objs(50, test(1));

这声明了vector个50个对象,每个对象都是test(1)的副本。 vector基本上是C ++可扩展数组;虽然你可能不需要可生长性,但是可以使用2-arg构造函数调用它来复制构造每个元素这一事实在这里很有用。

你可以使用这个或多或少完全像一个数组 - 例如第五个元素是objs[4]。性能也是一样的--C ++标准保证元素内部存储在连续的数组中。

答案 4 :(得分:0)

您不需要malloc()。您也可以使用new作为指针数组:

    test **objs = new test* [50];

答案 5 :(得分:0)

Boost的Pointer Container图书馆可能会来这里拯救。使用boost::ptr_vector<T>,您可以保存堆分配的对象列表,这些对象甚至可以是多态的(虚函数),这对于std::vector<T>来说是不可能的。

std::vector<T>不同,对象不会存储在后续的内存地址中。然而,调整容器大小的事情会更快,因为元素将保留其原始内存地址。最好的奖励是,您不需要自己调用delete:当ptr_vector超出范围时,包含的对象将被销毁。例如:

#include <boost/ptr_vector.hpp>
#include <iostream>
class test() {
protected:
    int const i;
public:
    explicit test(int i) : i(i) {}
    virtual void who_am_i() const { std::cout << "I am test " << i << std::endl; }
};
class special_test : public test {
public:
    explicit special_test(int i) : test(i) {}
    virtual void who_am_i() const { std::cout << "I am special_test " << i << std::endl; }
};
int main() {
    boost::ptr_vector<test> objs;
    for (int i=0; i<50; ++i)
        objs.push_back(new test(i)); // NB: constructing to heap here!
    objs.push_back(new special_test(123)); // objs can also hold inherited classes
    objs[13].who_am_i(); // outputs: I am test 13
    objs[50].who_am_i(); // outputs: I am special_test 123
} // all created objects are automatically destroyed here