對象沒有默認構造函數,如何定義對象數組?

class integer {
public:
int x;

public:
integer(int _x) : x(_x) {};
~interger() {
printf("des_integer
");
}
};

這個對象沒有空構造函數,所以不能寫類似於

integer *a = new integer[SIZE];

之類的語句,請問怎麼辦呢?


簡潔、高效、符合規範的方法:

vector& v(5, integer(0));
integer* data = v.data(); //返回vector內部的數組,data函數為c++11添加的函數

另一個技巧是:

struct integer_: public integer{ integer_():integer(0) {} };
integer* data = (integer*)new integer_[5];


鑒於你的integer似乎可以保證不拋異常, @Pluto Hades的方法應該能保證給你你所預期的效果,但那種實現談不上優雅,也沒有普適性。

最佳的方案應該是operator new + std::uninitialized_fill。

另外,為啥不用std::vector呢?


你可以簡單這樣(C++11):

Integer *p = new Integer[3]{ Integer(1), Integer(2), Integer(3) };

也可以這樣:

class Integer
{
public:
Integer(int _x) :x(_x) {}
~Integer() {}

int x;
};

int main()
{
const size_t size = 10;
Integer* array[size] = { nullptr };

for (size_t i = 0; i &< size; ++i) array[i] = new Integer(i); //do what you want for (size_t i = 0; i &< size; ++i) delete array[i]; return 0; }

或者使用allocator(頭文件memory),它將內存分配和對象構造進行了分離。

#include &

class Integer
{
public:
Integer(int _x) :x(_x) {}
~Integer() {}

int x;
};

int main()
{
std::allocator& alloc;

size_t size = 10;
Integer *p = alloc.allocate(size); //內存分配

for (size_t i = 0; i &< size; ++i) alloc.construct(p + i, Integer(i)); //對象構造 //do what you want for (size_t i = 0; i &< size; ++i) alloc.destroy(p + i); //對象析構 alloc.deallocate(p, size); //內存釋放 return 0; }


我很討厭截圖而不貼代碼,今天心情好,問題也不傻,原諒你了

雖然我覺得你的類完全可以寫無參構造,不過既然你誠心誠意地問了,我就大發慈悲的告訴你這裡要用placement new,詳情請谷歌placement new

下面直接上示例代碼:

#include & //使用placement new必須包含頭文件&

class integer {
public:
integer(int s): _x(s){}
~integer() {};

private:
int _x;
};

int main()
{
const size_t nSize = 10;

char* placement_space = new char[sizeof(integer) * nSize + sizeof(size_t)]; // 分配空間合適空間,並不調用構造
integer* pInteger = reinterpret_cast&(placement_space);// 指針強轉

for (size_t i = 0; i &< nSize; ++i) { new (pInteger + i)integer(123/*構造參數*/); // 使用placement new帶參構造 } // 干你想乾的事 for (size_t j = 0; j &< nSize; ++j) { pInteger[j].~integer();// 析構對象數組 } delete[] placement_space;// 釋放內存 //注意,分配和構造是兩步完成,析構和釋放也是兩步 return 0; }


列一個 @丁冬 提到的 operator new + std::uninitialized_fill 方式

class Integer
{
public:
Integer(int s) : _x(s) {}
~Integer () {}
private:
int _x;
};

int main ()
{
//placement new
void *placeMemory = operator new[](10*sizeof(Integer));
Integer *pInteger = static_cast&(placeMemory);

std::uninitialized_fill(pInteger, pInteger+10, 1);

//...
//destructor
for(size_t j=0; j&<10; ++j) { pInteger[j].~Integer(); } operator delete[](placeMemory); }

1 這裡分配空間用了operator new, 應該比new operator先分配個char型空間然後強轉更方便理解吧, 既然是最後要賦值成Integer類型, 那直接分配這個類型好了

2 實際上uninitialized_fill內部的實現就是placement new, 等效成

for(...)
{
new(pInteger[i]) Integer(1);
}


推薦閱讀:

python 的 tuple 是不是冗餘設計?
寫個編譯器,把C++代碼編譯到JVM的位元組碼可不可行?
C++中int A::*a里的指針a是什麼?
C/C++ 里指針聲明為什麼通常不寫成 int* ptr 而通常寫成 int *ptr ?
為什麼 C++ 中 a=b 會返回 a 的引用?

TAG:C | CC | C應用 | C入門 |