我有這個代碼
template <class ItemType>
class ArrTest {
public:
ArrTest();
private:
ItemType* info;
};
template <class ItemType>
ArrTest<ItemType>::ArrTest()
{
info = ItemType[50];
}
int main() {
ArrTest<int> ar();
return 0;
}
現在,當我嘗試構建它時,我得到了
../src/test1.cpp:23:9: error: 'ItemType' does not refer to a value
info = ItemType[50];
我不明白如何將其初始化為指標。我相信它是指向陣列中第一項的指標。但是我也應該能夠為陣列的第四個成員做 info[3] 。
uj5u.com熱心網友回復:
您需要使用new[]運算子來動態分配陣列:
template <class ItemType>
ArrTest<ItemType>::ArrTest()
: info(new ItemType[50])
{
}
然后,根據3/5/0 的規則,確保向delete[]'s 陣列添加解構式,并添加復制/移動建構式和復制/移動賦值運算子:
template <class ItemType>
class ArrTest {
public:
ArrTest();
ArrTest(const ArrTest &src);
ArrTest(ArrTest &&src);
~ArrTest();
ArrTest& operator=(ArrTest src);
private:
ItemType* info;
};
template <class ItemType>
ArrTest<ItemType>::ArrTest()
: info(new ItemType[50])
{
}
template <class ItemType>
ArrTest<ItemType>::ArrTest(const ArrTest &src)
: info(new ItemType[50])
{
std::copy(src.info, src.info 50, info);
}
template <class ItemType>
ArrTest<ItemType>::ArrTest(ArrTest &&src)
: info(nullptr)
{
std::swap(info, src.info);
}
template <class ItemType>
ArrTest<ItemType>::~ArrTest()
{
delete[] info;
}
template <class ItemType>
ArrTest<ItemType>& ArrTest<ItemType>::operator=(ArrTest<ItemType> src)
{
std::swap(info, src.info);
return *this;
}
一個更好的解決方案是改用std::vector它,讓它為您處理所有這些細節,例如:
#include <vector>
template <class ItemType>
class ArrTest {
public:
ArrTest();
private:
std::vector<ItemType> info;
};
template <class ItemType>
ArrTest<ItemType>::ArrTest()
: info(50)
{
}
無論哪種方式,ArrTest<int> ar(); 都不會像您期望的那樣宣告名為artype的默認構造變數。ArrTest<int>它宣告了一個名為的函式ar,它不帶引數并回傳一個ArrTest<int>,這不是你想要的。
為避免這種情況,您需要:
去掉括號:
ArrTest<int> ar;用花括號替換括號:
ArrTest<int> ar{};
uj5u.com熱心網友回復:
這種建設
info = ItemType[50];
在語法上無效。ItemType是一個型別,例如int,因為它是一個型別模板引數。所以你有類似的
info = int[50];
但右邊的運算式不是一個物件。它是一個型別說明符。所以編譯器會發出編譯錯誤。
請注意,如果您要撰寫如下內容
template <class ItemType>
ArrTest<ItemType>::ArrTest()
{
ItemType a[50];
info = a;
}
那么指標info將具有無效值,因為a在建構式中定義的區域陣列在退出建構式后將不存在。
uj5u.com熱心網友回復:
您可以使用建構式初始化串列和new,如下所示:
template <class ItemType>
//----------------------------vvvvvvvvvvvvvvvvvvvvvv-->added this
ArrTest<ItemType>::ArrTest(): info(new ItemType[50])
{
}
另請注意,ArrTest<int> ar();宣告了一個以ar回傳型別命名的函式,ArrTest<int>并且不帶引數。如果您打算創建一個型別的物件,ArrTest<int>則可以將其替換為:
ArrTest<int> ar{};
另外,不要忘記delete[]在不再需要時釋放相應的分配記憶體或使用a std::vector,這樣您就不必手動進行記憶體管理。
uj5u.com熱心網友回復:
一些答案建議使用new或者,甚至更好,std::vector. 如果數字元素是固定的并且在編譯時已知(例如50),您可以考慮
std::array:
#include <array>
template <class ItemType>
class ArrTest {
public:
private:
std::array<ItemType, 50> info;
};
或 C 風格的陣列:
template <class ItemType>
class ArrTest {
public:
private:
ItemType info[50];
};
使用這些解決方案,您無需實作解構式、復制/移動建構式和復制/移動賦值運算子。關于
std::vector解決方案,您沒有在堆上分配記憶體,因為陣列
info留在堆疊上。缺點是移動操作將花費您O(sizeof(info) / sizeof(ItemType))而不是O(1).
另外,請注意:
int main() {
ArrTest<int> ar0{};
// ^ This has all its elements initialized to int{} (i.e. (int)0)
ArrTest<int> ar1;
// ^ This has all its elements uninitialized!!
//ArrTest<int> ar2();
// ^ This declares a function!!
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/459539.html
