more effective c++ 第三條不要對陣列使用多型,在deleteArray函式在vs能呼叫成功,為什么?
uj5u.com熱心網友回復:
所謂多型是針對參考及指標的而陣列,對于每個元素,其實是值型別的資料,對他使用多型,會出錯。
uj5u.com熱心網友回復:
在陣列中,下標訪問陣列元素是按元素大小計算偏移地址的,array[i]相當于*(array + i * sizeof(T)),當把派生類陣列傳給一個基類陣列指標再進行訪問的時候,因為派生類和基類大小不一樣,導致偏移地址不一樣,就會出問題class CBase
{
public:
CBase() {}
virtual ~CBase() {}
};
class CDrived : public CBase
{
public:
CDrived() {}
~CDrived() {}
private:
int m_nData;
};
void FuncArray(const CBase arr[], int nCount)
{
std::cout << &arr[1] << std::endl;
}
int main()
{
CDrived arr[3];
std::cout << &arr[1] << std::endl;
FuncArray(arr, 3);
system("pause");
return 0;
}
運行結果:

可以看到輸出的兩個地址是不一樣的
uj5u.com熱心網友回復:
//vs2017
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
class BST
{
public:
virtual void print() const
{
cout << "BST";
}
};
class BalanceBst : public BST
{
public:
void print()
{
cout << "BalanceBst";
}
int a = 10;
int b = 20;
};
ostream &operator<<(ostream &os, const BST &item)
{
item.print();
return cout;
}
void printBSTArray(ostream &os, const BST array[], int n)
{
for ( int i = 0; i < n; ++i )
{
cout << array[i] << endl;
}
}
void deleteBSTArray(ostream &os, BST array[])
{
os << "Deleting array";
delete[] array;
}
//陣列保存基類物件,并列印
void test01()
{
BST BSTArray[5];
printBSTArray(cout, BSTArray, 5);
}
//陣列保存派生類物件并列印
void test02()
{
BalanceBst bBSTArray[5];
printBSTArray(cout, bBSTArray, 5);
}
//洗掉基類陣列
void test03()
{
BST *BSTArray = new BST[5];
deleteBSTArray(cout, BSTArray);
}
//洗掉派生類陣列
void test04()
{
BalanceBst *balBstArray = new BalanceBst[5];
deleteBSTArray(cout, balBstArray);
}
test02()因為陣列偏移會報錯,為什么test04()不會報錯?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/186680.html
標籤:新手樂園
