2011-03-17 96 views
17

首先,我想讓大家放心,因爲我好奇地問了這個問題。我的意思是,不要告訴我,如果我需要這個,那麼我的設計就會有問題,因爲我不需要真正的代碼。希望我相信你現在:)的問題:是否可以在C++中動態創建一個常量大小的數組?

對於大多數類型難道我們可以寫

T* p = new T; 

現在如果有什麼T是數組類型?

int (*p)[3] = new ???; //pointer to array of 3 = new ??? 

我嘗試這樣做:

typedef int arr[3]; 
arr* p = new arr; 

但這不起作用。

有沒有任何有效的語法,或者在C++中是不可能的。如果不可能,那爲什麼?由於

編輯:我猜測我是不太清楚。我希望能夠在這種情況下使用它:

void f(int(&)[3]); 
int (*p)[3] = new ???; 
f(*p); 
+0

如果我理解正確的話,你想知道C++是否有一種方法來「推斷」數組的大小,而不必在分配中明確指定它? – 2011-03-17 13:56:33

+0

@oakley:不太清楚:我問T是一個數組類型(具有編譯時已知維數)時是否使用'T * p = mew T;'語法 – 2011-03-17 13:58:08

回答

10

你不能這樣做的原因是new int[3]已經準確地分配了你想要的東西,一個int[3]類型的對象。這就是新表達式返回,是指向其第一個元素的指針。 5.3.4/1:

如果實體是一個非陣列對象, 新表達式返回一個指針 到創建的對象。如果它是一個 數組,則新表達式會返回指向 數組的初始元素的 指針。

返回一個指向第一個元素是什麼讓3是未知的,直到運行時,所以我想通過知道它提前,你絆倒了,你是不是使用的靈活性。我想這種方法是reinterpret_cast回到你想要的指針類型(不一定是便攜式),或分配一個包含int[3](並使用指向其數據成員的指針)的結構。

[編輯:呃,是的,或FredOverflow的想法,這既沒有缺點,但需要使用delete[]代替delete]

我猜的寓意是,如果你寫的模板,天真地分配一些未知類型Tnew,那麼當有人將數組類型傳遞爲T時,該模板將不起作用。你會將它分配給錯誤的指針類型,如果你修復了這個錯誤(可能是auto),你會錯誤地刪除它。

編輯在回答j_kubik的問題:

這裏的陣列和非陣列類型之間進行區分的方法之一。如果你寫這樣的功能,即返回包含指針,能夠正確地將其刪除的對象,那麼你有一個通用的新/刪除任何類型T.

#include <iostream> 

template <typename T> 
void make_thing_helper(T *) { 
    std::cout << "plain version\n"; 
} 

template <typename T, int N> 
void make_thing_helper(T (*)[N]) { 
    std::cout << "array version\n"; 
} 

template <typename T> 
void make_thing() { 
    make_thing_helper((T*)0); 
} 

int main() { 
    typedef int T1; 
    typedef int T2[3]; 
    make_thing<T1>(); 
    make_thing<T2>(); 
} 
+1

兩個'新INT [3]'和'新INT [1] [3]'已被釋放通過'delete []'。 – fredoverflow 2011-03-17 14:31:13

+1

@FredOverflow:的確,我的意思是「而不是」,非數組類型會發生什麼,如果我正在發明Armen想要的魔法不存在的語法,那麼要分配一個數組類型的單個對象*好像它是一個非數組類型,那麼它會讓你通過從'MagicNew'返回的同一個指針'delete'來刪除它,所以它看起來像'typedef int arr [3]; arr * p = MagicNew arr; delete p;'我知道他沒有在他的問題中指明這一點,也許我錯誤地認爲其他人會以同樣的方式創造它 – 2011-03-17 14:36:35

+0

所以總結 - 有沒有辦法新的刪除模板準備好了陣列類型還是簡直不可能? – 2011-09-06 06:22:06

-2

你只是做

int *p = new unsigned int [3] 

然後可以使用*p爲指針或數組即*(p+1) or p[1]

+2

對不起,但這不是我所能問。在所有 – 2011-03-17 13:55:00

11

爲了得到一個指針從new到數組,您必須動態分配一個二維數組:

int (*p)[3] = new int[1][3]; 
+0

嗯......不完全是我期待的,但我的例子肯定會工作...... +1 – 2011-03-17 14:02:12

2

你總是可以使用boost :: array,它將在C++ 0x中。否則,任何解決方案在最好情況下都會很尷尬:數組是 以C分解,而C++在此方面與C保持相容性。 Fred Overflow提供了一個解決方案;甚至更容易(但 句法噪聲)將包裝在結構中的數組:結構A {int arr [3]; }; 並分配和操作它。

+0

這將是一個解決方法,而不是解決方案:)而@弗雷德的也是,但至少我的例子與他的工作解決方法。與你的,它不會,是嗎? – 2011-03-17 14:08:03

+1

包裝是一種解決方法,但boost:array將是我的首選解決方案,用於處理固定大小的數組。所以奇怪,但可能的:空隙F(陣列<3> & p);陣列<3> * p值=新的數組<3>; F(* P); – stefaanv 2011-03-17 14:39:07

相關問題