比如有類似下面代碼
class People{
};
class Student : public People{
};
void printPeopleInfo(const People* peoples , int len);
假如我設計了一份SDK,printPeopleInfo()這個函式用以列印People類,但如果如下呼叫
Student student[] = {/*十個Student*/};
printPeopleInfo(students , 10);
編譯沒問題,但運行階段很有可能出現問題了,所以我希望在printPeopleInfo()函式內檢測下,傳入的引數是不是People類,如果不是(比如傳入了繼承自People類),我希望編譯階段就能報錯,有沒有辦法實作?
uj5u.com熱心網友回復:
people父類中定義一個虛函式,student子類重寫。該方法用于回傳當前的類名,方便檢測。uj5u.com熱心網友回復:
more effective c++ 第三條不要對陣列使用多型。你那種想法就不行!uj5u.com熱心網友回復:
可以用模板啊#include <iostream>
#include <type_traits>
class A {};
class B : A {};
class C {};
int main()
{
std::cout << std::boolalpha;
std::cout << "a2b: " << std::is_base_of<A, B>::value << '\n';
std::cout << "b2a: " << std::is_base_of<B, A>::value << '\n';
std::cout << "c2b: " << std::is_base_of<C, B>::value << '\n';
std::cout << "same type: " << std::is_base_of<C, C>::value << '\n';
}
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熱心網友回復:
那如果
我就是看了這個條款才想到這個問題的,我設計的SDK,我希望別人使用時,如果傳入了基類,我的函式可以在編譯階段報錯
uj5u.com熱心網友回復:
謝謝,我去試試
uj5u.com熱心網友回復:
某些語言可以直接用is運算子判斷,但是c++不支持而且
void printPeopleInfo(const People* peoples , int len);
引數是一個指向People型別的指標,* peoples的實際型別在函式內部無法判斷
另外,is_base_of只能針對型別,而不是變數,或者一個變數一個型別
uj5u.com熱心網友回復:
A a1;B b1;
std::cout << std::boolalpha;
std::cout << "a2b: " << std::is_base_of<decltype(a1), decltype(b1)>::value << '\n';
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/195648.html
標籤:C++ 語言
上一篇:函式回傳值問題!
