abstract中如何使用class 抽象類,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
成都創(chuàng)新互聯(lián)公司專注于梓潼企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),商城網(wǎng)站定制開發(fā)。梓潼網(wǎng)站建設(shè)公司,為梓潼等地區(qū)提供建站服務(wù)。全流程按需求定制設(shè)計(jì),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
首先來說虛函數(shù);
虛函數(shù)是在基類中被聲明為virtual,并在派生類中重新定義的成員函數(shù),可實(shí)現(xiàn)函數(shù)的動(dòng)態(tài)重載;
動(dòng)態(tài)重載也就是在可以依據(jù)后期的傳入類的類型,選擇具體的實(shí)現(xiàn)函數(shù);
純虛函數(shù)的聲明有著特殊的語法格式:virtual 返回值類型成員函數(shù)名(參數(shù)表)=0;
包含有虛函數(shù)是成為抽象類的充要條件;
包含了虛函數(shù)的類被稱為抽象類,抽象類中可以有純虛函數(shù),也可以有其他非虛函數(shù);因?yàn)槌橄箢愔卸际菦]有定義的虛函數(shù),因此不能定義對(duì)象;
在C++中,我們可以把只能用于被繼承而不能直接創(chuàng)建對(duì)象的類設(shè)置為抽象類(Abstract Class)。
舉一個(gè)小栗子~~
比如我今天想寫一個(gè)代碼,可以自動(dòng)幫我炒肉菜,我需要實(shí)現(xiàn)的效果是,如果傳入雞肉,則做宮保雞??;如果傳入排骨,則做土豆燉排骨;如果傳入牛肉,則做成黑椒牛仔骨;每次 只做一道菜;
因?yàn)闊o法預(yù)料到具體使用時(shí)可能會(huì)傳入的肉的類型,總不能三個(gè)對(duì)象都創(chuàng)建?這個(gè)時(shí)候可以創(chuàng)建抽象類 肉類;以及派生類 雞肉,排骨,和牛肉;
這三個(gè)類中都需要有對(duì)應(yīng)做菜的函數(shù),如cook();
#includeusing namespace std; class Meat //抽象類:肉類 { public: virtual void cook()=0;//純虛函數(shù) }; class Chicken:public Meat //派生類:雞肉 { public: void cook(){ cout<<"熱鍋下油,加入黃瓜丁和胡蘿卜丁翻炒至半熟,劃入雞丁翻炒,最后放入買好的宮保雞丁醬和花生米即可" cook(); return 0; }
大概的一個(gè)例子,不知道有沒有解釋清楚,有問題歡迎指正,在上面的例子中也能看到,抽象類是不能創(chuàng)建對(duì)象的,但是可以定義指針指向抽象類;
抽象類的規(guī)定
(1)抽象類只能用作其他類的基類,不能建立抽象類對(duì)象。
(2)抽象類不能用作參數(shù)類型、函數(shù)返回類型或顯式轉(zhuǎn)換的類型。
(3)可以定義指向抽象類的指針和引用,此指針可以指向它的派生類,進(jìn)而實(shí)現(xiàn)多態(tài)性。
在ORBSLAM3中的使用,也說明了抽象類存在的意義,也就是實(shí)現(xiàn)了多態(tài);可以把它理解成一個(gè)操作接口,具體的實(shí)現(xiàn)在派生類中;
ORBSLAM3中因?yàn)樾录尤肓薑B模型,這就導(dǎo)致無法在最一開始后時(shí)候確定相機(jī)的類型,是普通針孔相機(jī)(Pinhole) 還是魚眼相機(jī)(使用KB);
如果不使用抽象類的話,以單目相機(jī)為例,除了需要為Pinhole和KB各自創(chuàng)建一個(gè)類,同時(shí)在需要使用相機(jī)參數(shù)的時(shí)候,定義兩個(gè)對(duì)象,一個(gè)Pinhole,一個(gè)KB;
然后,在使用時(shí),只使用其中的一個(gè);
有了抽象類,就可以先將相機(jī)的模型聲明成一個(gè)抽象的類型:GeometricCamera* mpCamera;然后按照配置文件中的輸入是Pinhole還是KannalaBrandt8, 定義對(duì)象mpCamera即可;如:
mpCamera = new Pinhole(vCamCalib); //或者 mpCamera = new KannalaBrandt8(vCamCalib);
同時(shí),因?yàn)槟P筒煌?,不同坐?biāo)系之間的轉(zhuǎn)換函數(shù)也會(huì)不同,以投影函數(shù)為例:
首先在抽象類中定義一個(gè)虛函數(shù):
virtual cv::Point2f project(const cv::Point3f &p3D) = 0;
然后具體的實(shí)現(xiàn)時(shí), 在KB模型中為
cv::Point2f KannalaBrandt8::project(const cv::Point3f &p3D) { const float x2_plus_y2 = p3D.x * p3D.x + p3D.y * p3D.y; const float theta = atan2f(sqrtf(x2_plus_y2), p3D.z); const float psi = atan2f(p3D.y, p3D.x); const float theta2 = theta * theta; const float theta3 = theta * theta2; const float theta5 = theta3 * theta2; const float theta7 = theta5 * theta2; const float theta9 = theta7 * theta2; const float r = theta + mvParameters[4] * theta3 + mvParameters[5] * theta5 + mvParameters[6] * theta7 + mvParameters[7] * theta9; return cv::Point2f(mvParameters[0] * r * cos(psi) + mvParameters[2], mvParameters[1] * r * sin(psi) + mvParameters[3]); }
在Pinhole中為:
cv::Point2f Pinhole::project(const cv::Point3f &p3D) { return cv::Point2f(mvParameters[0] * p3D.x / p3D.z + mvParameters[2], mvParameters[1] * p3D.y / p3D.z + mvParameters[3]); }
使用時(shí)按照傳入相機(jī)的類型,mpCamera->project(p3D) 代碼會(huì)根據(jù)相機(jī)的類型自動(dòng)調(diào)用對(duì)應(yīng)的實(shí)現(xiàn)函數(shù);
a. invalid new-expression of abstract class type ‘×××ב
這種情況一般是抽象類中的虛函數(shù),并沒有在派生類中被實(shí)現(xiàn),也就是派生類中沒有定義;一般編譯的時(shí)候會(huì)指示出具體的問題出處,如下面:
src/Tracking.cc: In member function ‘bool ORB_SLAM2::Tracking::ParseCamParamFile(cv::FileStorage&)’: src/Tracking.cc:169:34: error: invalid new-expression of abstract class type ‘ORB_SLAM2::EUCM’ mpCamera = new EUCM(vCamCalib); ^ In file included from src/Tracking.cc:28:0: /include/CameraModels/EUCM.h:12:7: note: because the following virtual functions are pure within ‘ORB_SLAM2::EUCM’: class EUCM final : public GeometricCamera{ ^ In file included from include/Tracking.h:30:0, from src/Tracking.cc:21: include/CameraModels/GeometricCamera.h:38:29: note: virtual cv::Point2f ORB_SLAM2::GeometricCamera::Camera2Img(const cv::Mat&) virtual cv::Point2f Camera2Img(const cv::Mat& m3D) = 0;
指出了抽象類中的Camera2Img() 在派生類EUCM中沒有對(duì)應(yīng)的實(shí)現(xiàn),而其實(shí)我這里有對(duì)應(yīng)的函數(shù),但是形參類型寫錯(cuò)了;
b. C++ : Cannot declare field to be of abstract type
這里是抽象類的實(shí)例化問題,也就是上面說到的,抽象類并不能定義對(duì)象,但是可以定義指向抽象類的指針;上面炒菜的例子中,如果我定義:
Meat realmeat;
就會(huì)出現(xiàn)類似的報(bào)錯(cuò),但是定義
Meat *realmeat;
看完上述內(nèi)容,你們掌握abstract中如何使用class 抽象類的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!