锘??xml version="1.0" encoding="utf-8" standalone="yes"?> QFontDatabase鐨勬瀯閫犲嚱鏁頒腑浼氳皟鐢╟reateDatabase 錛堥噷闈㈣皟鐢ㄤ簡initializeDb), initializeDb閲岃皟鐢ㄤ簡privateDb(),涓涓繖涓椂鍊欐槸絎竴嬈¤皟鐢紝 浼氱敓鎴怮FontDatabasePrivate瀵硅薄 QFontDatabasePrivate涓殑QDataStream *stream鎴愬憳鎵嶆槸鐪熸澶勭悊qte鐨勫瓧浣?/p> 鍒涘緩涓涓猀T鐨勫簱欏圭洰,鍒犻櫎鑷姩鐢熸垚鐨?h鍜?cpp鏂囦歡,娣誨姞涓涓帴鍙e畾涔?h鏂囦歡鍜屼竴涓帴鍙e疄鐜扮被(涓涓?h涓涓?cpp).浠g爜濡備笅: 1.鎺ュ彛鏂囦歡婧愮爜 #ifndef PLUGININTERFACE_H #include <QString> QT_BEGIN_NAMESPACE 2.鎺ュ彛瀹炵幇綾誨ご鏂囦歡 #ifndef PLUGIN_H //#include "plugin_global.h" class Plugin : public QObject, EchoInterface #endif // PLUGIN_H 3.鎺ュ彛瀹炵幇綾籧pp鏂囦歡 #include "plugin.h" } Plugin::~Plugin() } QString Plugin::echo(const QString &message) Q_EXPORT_PLUGIN2("echoPlugin", Plugin); 緙栬瘧鐢熸垚dll鏍煎紡鐨勬彃浠?榪欓噷鍙兘浼氶亣鍒癓NK2001閿欒,鍥犱負鎻掍歡鎺ュ彛瀹氫箟渚濊禆浜嶲T鐨勫厓鏁版嵁,鑰屽湪浠g爜涓墜鍔ㄦ坊鍔燪_OBJECT瀹忓悗,緙栬瘧鍣ㄤ笉浼氳嚜鍔ㄤ負鎴戜滑鐢熸垚moc_XXXX.cpp鏂囦歡,鍥犳闇瑕佷嬌鐢ㄥ懡浠よ鐢熸垚moc鍏冩暟鎹枃浠?cmd-->cd 婧愮爜鎵鍦ㄥ懡浠?-->moc -o moc_XXXX.cpp XXXX.h.榪欐牱灝卞彲浠ユ墜鍔ㄥ垱寤哄嚭moc鍏冩暟鎹枃浠?瑙e喅LNK2001緙栬瘧閿欒. 寤虹珛涓涓狦UI嫻嬭瘯欏圭洰,浠g爜濡備笅: #include "test.h" Test::Test(QWidget *parent, Qt::WFlags flags) Test::~Test() } bool Test::loadPlugin() void Test::ButtonClicked() 鍒嗘瀽浠g爜鍙,榪欓噷瀵規墍鏈変笌exe鏂囦歡鍚岀洰褰曠殑鏂囦歡灝濊瘯鍔犺澆鎻掍歡,濡傛灉鍔犺澆鎴愬姛鍒欒繑鍥?浠g爜瀹炵幇闈炲父綆媧?鍦ㄦ寮忓紑鍙戜腑鍙皢宸插姞杞界殑鎻掍歡鎺ュ彛瀛樻斁鍦ㄥ垪琛ㄤ腑,鍦ㄩ渶瑕佺殑鏃跺欎緷嬈¤皟鐢ㄥ嵆鍙? 鍙﹀濡傛灉鎯寵幏鍙栨彃浠朵腑綾誨畾涔夌殑鍏冩暟鎹?鍙互浣挎彃浠舵帴鍙g被浠嶲Object緇ф壙,騫朵嬌鐢≦_CLASSINFO瀹忔坊鍔犻敭鍊煎,濡俀_CLASSINFO("Author**", "Henreash**").騫朵粠涓葷▼搴忎腑浣跨敤鎻掍歡瀵硅薄鍏冩暟鎹幏鍙栬繖浜涢敭鍊煎: const QMetaObject *mo = echoInterface->metaObject(); 浣跨敤榪欎釜鏈哄埗鍙互鍦ㄥ畾涔夋彃浠剁被鐨勬椂鍊欏悜涓葷▼搴忎紶閫掍竴浜涚壒孌婁俊鎭? 嫻嬭瘯鍙戠幇,濡傛灉鍦ㄦ彃浠舵帴鍙g被涓畾涔変竴涓潤鎬佸彉閲?閭d箞榪欎釜闈欐佸彉閲忓湪鎻掍歡涓殑鍦板潃鍜屽湪涓葷▼搴忎腑鐨勫湴鍧鏄笉鐩稿悓鐨?
@import url(http://www.shnenglu.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
]]>
// [[1]] 浣跨敤typedef瀹氫箟鍑芥暟鎸囬拡涓轟竴涓被鍨嬶紝鏇村枩嬈㈣繖縐嶆柟寮?/font>
typedef int (*MYFUN)(int, int);
MYFUN funcs[10];
// [[2]] 浣跨敤typedef瀹氫箟鍑芥暟鎸囬拡鏁扮粍涓轟竴涓被鍨嬶紝涓嶆槸寰堢洿瑙?/font>
typedef int (*MYFUN2[10])(int, int);
MYFUN2 funcs2;
int main(int argc, char *argv[]) {
funcs[0] = add;
qDebug() << (*funcs[0])(2, 3); // 涔熷彲浠ョ敤 funcs[0](2, 3).
funcs2[0] = add;
qDebug() << (*funcs2[0])(2, 3);
return 0;
}
@import url(http://www.shnenglu.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
]]>
鏍規嵁 src/corelib/global.h template <typename T>
class QGlobalStatic
{
public:
T *pointer;
inline QGlobalStatic(T *p) : pointer(p) { }
inline ~QGlobalStatic() { pointer = 0; }
};
#define Q_GLOBAL_STATIC(TYPE, NAME) \
static TYPE *NAME() \
{ \
static TYPE this_##NAME; \
static QGlobalStatic<TYPE > global_##NAME(&this_##NAME); \
return global_##NAME.pointer; \
}
涓婇潰鐨勫睍寮鎴?/span> static QFontDatabasePrivate *privateDb()
{
static QFontDatabasePrivate this_privateDb; // 娉ㄦ剰絎竴嬈″紩鐢ㄧ殑鏃跺欎細寮濮嬭繘琛屽垵濮嬪寲, 浠ュ悗涓嶅啀鐢熸垚
static QGLobalStatic<QFontDatabasePrivate> global_privateDb(&this_privateDb); //瀵逛笂闈㈢敓鎴愮殑瀵硅薄鐨勬寚閽堣繘琛屽寘瑁咃紝 鍚屼笂錛屽彧鏈夌涓嬈℃墠浼氱敓鎴?br />
return global_privateDb;
}
#define PLUGININTERFACE_H
class EchoInterface
{
public:
virtual ~EchoInterface() {}
virtual QString echo(const QString &message) = 0;
};
Q_DECLARE_INTERFACE(EchoInterface, "com.hollysys.plugin.EchoIntrface/1.0");
QT_END_NAMESPACE
#endif
#define PLUGIN_H
#include <QObject>
#include "plugininterface.h"
{
Q_OBJECT
Q_INTERFACES(EchoInterface)
public:
Plugin();
~Plugin();
public:
QString echo(const QString &message);
};
#include <QtGui>
Plugin::Plugin()
{
{
{
return message;
}
#include <QtGui>
#include <QMessageBox>
#include <QDir>
: QMainWindow(parent, flags)
{
ui.setupUi(this);
QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(ButtonClicked()));
loadPlugin();
}
{
{
QDir pluginsDir(qApp->applicationDirPath());
foreach (QString filename, pluginsDir.entryList(QDir::Files))
{
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(filename));
QObject *plugin = pluginLoader.instance();
if(plugin)
{
echoInterface = qobject_cast<EchoInterface *>(plugin);//echoInterface鏄垚鍛樺彉閲?br />
if(echoInterface)
return true;
}
}
}
{
QString plugin = ui.lineEdit->text();
QMessageBox::information(NULL, "", echoInterface->echo(plugin));
}
for(int i = 0; i < mo->classInfoCount(); i++)
{
qDebug() << mo->classInfo(i).name() << mo->classInfo(i).value();
}
]]>
鍦?a title="C++" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">C++緙栫▼璇█涓紝鍗曚緥妯″紡搴旂敤鐨勪緥瀛愬涓嬭堪浠g爜鎵紺猴紙榪欓噷浠呬粎鎻愪緵涓涓ず渚嬶紝榪欎釜渚嬪瓙瀵瑰綰跨▼鐨勬儏鍐靛茍涓嶆槸瀹夊叏鐨勶級錛?/p>
// ... class lock { public: lock(); lock(lock const & l); ~lock(); lock & operator =(lock const & l); void request(); void release(); // ... }; lock::lock() { // ... } // ... lock::~lock() { // ... } // ... void lock::request() { // ... } void lock::release() { // ... } // ... // assumes _DATA_TYPE_ has a default constructor template<typename _DATA_TYPE_> class singleton { public: static _DATA_TYPE_ * request(); static void release(); private: singleton(); singleton(singleton<_DATA_TYPE_> const & s); ~singleton(); singleton<_DATA_TYPE_> & operator =(singleton<_DATA_TYPE_> const & s); static _DATA_TYPE_ * pointer; static lock mutex; // ... }; template<typename _DATA_TYPE_> _DATA_TYPE_ * singleton<_DATA_TYPE_>::pointer = 0; template<typename _DATA_TYPE_> lock singleton<_DATA_TYPE_>::mutex; template<typename _DATA_TYPE_> _DATA_TYPE_ * singleton<_DATA_TYPE_>::request() { if(singleton<_DATA_TYPE_>::pointer == 0) { singleton<_DATA_TYPE_>::mutex.request(); if(singleton<_DATA_TYPE_>::pointer == 0) { singleton<_DATA_TYPE_>::pointer = new _DATA_TYPE_; } singleton<_DATA_TYPE_>::mutex.release(); } return singleton<_DATA_TYPE_>::pointer; } template<typename _DATA_TYPE_> void singleton<_DATA_TYPE_>::release() { if(singleton<_DATA_TYPE_>::pointer != 0) { singleton<_DATA_TYPE_>::mutex.request(); if(singleton<_DATA_TYPE_>::pointer != 0) { delete singleton<_DATA_TYPE_>::pointer; singleton<_DATA_TYPE_>::pointer = 0; } singleton<_DATA_TYPE_>::mutex.release(); } } template<typename _DATA_TYPE_> singleton<_DATA_TYPE_>::singleton() { // ... } // ... int main() { int * s; s = singleton<int>::request(); // ... singleton<int>::release(); return 0; }
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Tutors | ![]() |
Tutors source code package (tutors-src.zip 920KB) Source package + Windows executables (tutors-win32.zip 1.24MB) Source package + Mac OS X universal binaries (tutors-macosx.zip 1.2MB) Contributions from various people (Unix makefiles, etc). |
||
|
||
|
||
The lightmaterial tutorial program (shown above) demonstrates how OpenGL lighting and material properties interact and effect each other. All material & light properties are tweakable. A second command panel allows spotlight parameters & attenuation factors to be changed. |
||
|
||
|
||
The texture tutorial program (shown above) demonstrates how OpenGL texturing works. Specifically, the texture coordinates for a polygon are provided for manipulation as are the polygons coordinates themselves. The texture parameter & environment attributes are tweakable. A separate command panel allows manipulation of the texture matrix. |
||
|
![]() |
![]() |
![]() |
錛?錛夋樉寮忛摼鎺?/strong>
闇瑕佸嚱鏁版寚閽堝拰WIN32 API鍑芥暟LoadLibrary銆丟etProcAddress瑁呰澆錛屼嬌鐢ㄨ繖縐嶈澆鍏ユ柟娉曪紝涓嶉渶瑕?lib鏂囦歡鍜?h澶存枃浠訛紝鍙渶瑕?dll鏂囦歡鍗沖彲錛堝皢.dll鏂囦歡緗叆宸ョ▼鐩綍涓級銆?/span>
LoadLibrary鍑芥暟鍒╃敤涓涓悕縐頒綔涓哄弬鏁幫紝鑾峰緱DLL鐨勫疄渚嬶紙HINSTANCE綾誨瀷鏄疄渚嬬殑鍙ユ焺錛夛紝閫氬父璋冪敤璇ュ嚱鏁板悗闇瑕佹煡鐪嬩竴涓嬪嚱鏁拌繑鍥炴槸鍚︽垚鍔燂紝濡傛灉涓嶆垚鍔熷垯榪斿洖NULL錛堝彞鏌勬棤鏁堬級錛屾鏃惰皟鐢ㄥ嚱鏁癋reeLibrary閲婃斁DLL鑾峰緱鐨勫唴瀛樸?/span>
GetProcAddress鍑芥暟鍒╃敤DLL鐨勫彞鏌勫拰鍑芥暟鐨勫悕縐頒綔涓哄弬鏁幫紝榪斿洖鐩稿簲鐨勫嚱鏁版寚閽堬紝鍚屾椂蹇呴』浣跨敤寮鴻漿錛涘垽鏂嚱鏁版寚閽堟槸鍚︿負NULL錛屽鏋滄槸鍒欒皟鐢ㄥ嚱鏁癋reeLibrary閲婃斁DLL鑾峰緱鐨勫唴瀛樸傛鍚庯紝鍙互浣跨敤鍑芥暟鎸囬拡鏉ヨ皟鐢ㄥ疄闄呯殑鍑芥暟銆?/span>
鏈鍚庤璁板緱浣跨敤FreeLibrary鍑芥暟閲婃斁鍐呭瓨銆?/span>
娉ㄦ剰錛氬簲鐢ㄧ▼搴忓浣曟壘鍒癉LL鏂囦歡錛?/span>
浣跨敤LoadLibrary鏄懼紡閾炬帴錛岄偅涔堝湪鍑芥暟鐨勫弬鏁頒腑鍙互鎸囧畾DLL鏂囦歡鐨勫畬鏁磋礬寰勶紱濡傛灉涓嶆寚瀹氳礬寰勶紝鎴栬呰繘琛岄殣寮忛摼鎺ワ紝Windows灝嗛伒寰笅闈㈢殑鎼滅儲欏哄簭鏉ュ畾浣岲LL錛?/span>
錛?錛夊寘鍚獷XE鏂囦歡鐨勭洰褰?/span>
錛?錛夊伐紼嬬洰褰?/span>
錛?錛塛indows緋葷粺鐩綍
錛?錛塛indows鐩綍
錛?錛夊垪鍦≒ath鐜鍙橀噺涓殑涓緋誨垪鐩綍
From: http://www.shnenglu.com/ming81/archive/2013/03/04/198215.html
.h澶存枃浠舵槸緙栬瘧鏃跺繀欏葷殑錛宭ib鏄摼鎺ユ椂闇瑕佺殑錛宒ll鏄繍琛屾椂闇瑕佺殑銆?/span>
闄勫姞渚濊禆欏圭殑鏄?lib涓嶆槸.dll錛岃嫢鐢熸垚浜咲LL,鍒欒偗瀹氫篃鐢熸垚 LIB鏂囦歡銆傚鏋滆瀹屾垚婧愪唬鐮佺殑緙栬瘧鍜岄摼鎺ワ紝鏈夊ご鏂囦歡鍜宭ib灝卞浜嗐傚鏋滀篃浣垮姩鎬佽繛鎺ョ殑紼嬪簭榪愯璧鋒潵錛屾湁dll灝卞浜嗐傚湪寮鍙戝拰璋冭瘯闃舵錛屽綋鐒舵渶濂介兘鏈夈?/span>
.h .lib .dll涓夎呯殑鍏崇郴鏄細
H鏂囦歡浣滅敤鏄?澹版槑鍑芥暟鎺ュ彛
DLL鏂囦歡浣滅敤鏄? 鍑芥暟鍙墽琛屼唬鐮?nbsp;
褰撴垜浠湪鑷繁鐨勭▼搴忎腑寮曠敤浜嗕竴涓狧鏂囦歡閲岀殑鍑芥暟,緙栭摼鍣ㄦ庝箞鐭ラ亾璇ヨ皟鐢ㄥ摢涓狣LL鏂囦歡鍛?榪欏氨鏄疞IB鏂囦歡鐨勪綔鐢? 鍛婅瘔閾炬帴鍣?璋冪敤鐨勫嚱鏁板湪鍝釜DLL涓紝鍑芥暟鎵ц浠g爜鍦―LL涓殑浠涔堜綅緗?錛岃繖涔熷氨鏄負浠涔堥渶瑕侀檮鍔犱緷璧栭」 .LIB鏂囦歡錛屽畠璧峰埌妗ユ鐨勪綔鐢ㄣ傚鏋滅敓鎴愰潤鎬佸簱鏂囦歡錛屽垯娌℃湁DLL 錛屽彧鏈塴ib錛岃繖鏃跺嚱鏁板彲鎵ц浠g爜閮ㄥ垎涔熷湪lib鏂囦歡涓?/span>
鐩墠浠ib鍚庣紑鐨勫簱鏈変袱縐嶏紝涓縐嶄負闈欐侀摼鎺ュ簱(Static Libary錛屼互涓嬬畝縐?#8220;闈欐佸簱”)錛屽彟涓縐嶄負鍔ㄦ佽繛鎺ュ簱(DLL錛屼互涓嬬畝縐?#8220;鍔ㄦ佸簱”)鐨勫鍏ュ簱(Import Libary錛屼互涓嬬畝縐?#8220;瀵煎叆搴?#8221;錛夈傞潤鎬佸簱鏄竴涓垨鑰呭涓猳bj鏂囦歡鐨勬墦鍖?錛屾墍浠ユ湁浜哄共鑴嗘妸浠巓bj鏂囦歡鐢熸垚lib鐨勮繃紼嬬О涓篈rchive錛屽嵆鍚堝茍鍒頒竴璧楓傛瘮濡備綘閾炬帴涓涓潤鎬佸簱錛屽鏋滃叾涓湁閿欙紝瀹冧細鍑嗙‘鐨勬壘鍒版槸鍝釜obj鏈夐敊錛屽嵆闈欐乴ib鍙槸澹沖瓙銆傚姩鎬佸簱涓鑸細鏈夊搴旂殑瀵煎叆搴擄紝鏂逛究紼嬪簭闈欐佽澆鍏ュ姩鎬侀摼鎺ュ簱 錛屽惁鍒欎綘鍙兘灝遍渶瑕佽嚜宸盠oadLibary璋冨叆DLL鏂囦歡錛岀劧鍚庡啀鎵嬪伐GetProcAddress鑾峰緱瀵瑰簲鍑芥暟浜嗐傛湁浜嗗鍏ュ簱錛屼綘鍙渶瑕侀摼鎺ュ鍏ュ簱鍚庢寜鐓уご鏂囦歡鍑芥暟鎺ュ彛鐨勫0鏄庤皟鐢ㄥ嚱鏁板氨鍙互浜嗐傚鍏ュ簱鍜岄潤鎬佸簱鐨勫尯鍒緢澶э紝浠栦滑瀹炶川鏄笉涓鏍風殑涓滆タ銆傞潤鎬佸簱鏈韓灝卞寘鍚簡瀹為檯鎵ц浠g爜銆佺鍙瘋〃絳夌瓑錛岃屽浜庡鍏ュ簱鑰岃█錛屽叾瀹為檯鐨勬墽琛屼唬鐮佷綅浜庡姩鎬佸簱涓紝瀵煎叆搴撳彧鍖呭惈浜嗗湴鍧絎﹀彿琛ㄧ瓑錛岀‘淇濈▼搴忔壘鍒板搴斿嚱鏁扮殑涓浜涘熀鏈湴鍧淇℃伅銆?/span>
涓鑸殑鍔ㄦ佸簱紼嬪簭鏈塴ib鏂囦歡鍜宒ll鏂囦歡銆俵ib鏂囦歡鏄繀欏誨湪緙栬瘧鏈熷氨榪炴帴鍒板簲鐢ㄧ▼搴忎腑鐨勶紝鑰宒ll鏂囦歡鏄繍琛屾湡鎵嶄細琚皟鐢ㄧ殑銆?濡傛灉鏈塪ll鏂囦歡錛岄偅涔堝搴旂殑lib鏂囦歡涓鑸槸涓浜涚儲寮曚俊鎭紝鍏蜂綋鐨勫疄鐜板湪dll鏂囦歡涓傚鏋滃彧鏈塴ib鏂囦歡錛岄偅涔堣繖涓猯ib鏂囦歡鏄潤鎬佺紪璇戝嚭鏉ョ殑錛岀儲寮曞拰瀹炵幇閮藉湪鍏朵腑銆傞潤鎬佺紪璇戠殑lib鏂囦歡鏈夊ソ澶勶細緇欑敤鎴峰畨瑁呮椂灝變笉闇瑕佸啀鎸傚姩鎬佸簱浜嗐備絾涔熸湁緙虹偣錛屽氨鏄鑷村簲鐢ㄧ▼搴忔瘮杈冨ぇ錛岃屼笖澶卞幓浜嗗姩鎬佸簱鐨勭伒媧繪э紝鍦ㄧ増鏈崌綰ф椂錛屽悓鏃惰鍙戝竷鏂扮殑搴旂敤紼嬪簭鎵嶈銆傚湪鍔ㄦ佸簱鐨勬儏鍐典笅錛屾湁涓や釜鏂囦歡錛岃屼竴涓槸寮曞叆搴擄紙.LIB錛夋枃浠訛紝涓涓槸DLL鏂囦歡錛屽紩鍏ュ簱鏂囦歡鍖呭惈琚獶LL瀵煎嚭鐨勫嚱鏁扮殑鍚嶇О鍜屼綅緗紝DLL鍖呭惈瀹為檯鐨勫嚱鏁板拰鏁版嵁錛屽簲鐢ㄧ▼搴忎嬌鐢↙IB鏂囦歡閾炬帴鍒版墍闇瑕佷嬌鐢ㄧ殑DLL鏂囦歡錛屽簱涓殑鍑芥暟鍜屾暟鎹茍涓嶅鍒跺埌鍙墽琛屾枃浠朵腑錛屽洜姝ゅ湪搴旂敤紼嬪簭鐨勫彲鎵ц鏂囦歡涓紝瀛樻斁鐨勪笉鏄璋冪敤鐨勫嚱鏁頒唬鐮侊紝鑰屾槸DLL涓墍瑕佽皟鐢ㄧ殑鍑芥暟鐨勫唴瀛樺湴鍧錛岃繖鏍峰綋涓涓垨澶氫釜搴旂敤紼嬪簭榪愯鏄啀鎶婄▼搴忎唬鐮佸拰琚皟鐢ㄧ殑鍑芥暟浠g爜閾炬帴璧鋒潵錛屼粠鑰岃妭鐪佷簡鍐呭瓨璧勬簮銆備粠涓婇潰鐨勮鏄庡彲浠ョ湅鍑猴紝DLL鍜?LIB鏂囦歡蹇呴』闅忓簲鐢ㄧ▼搴忎竴璧峰彂琛岋紝鍚﹀垯搴旂敤紼嬪簭灝嗕細浜х敓閿欒銆?/span>
闈欐佸簱鍜屽叡浜簱閮芥槸涓涓猳bj鏂囦歡鐨勯泦鍚?錛屼絾闈欐侀摼鎺ュ悗錛屾墽琛岀▼搴忎腑瀛樺湪鑷繁鎵闇obj鐨勪竴浠芥嫹璐濓紝鑰屽姩鎬侀摼鎺ュ悗錛屾墽琛岀▼搴忎粎浠呮槸鍖呭惈瀵瑰叡浜簱鐨勪竴涓紩鐢ㄣ傚叡浜簱鐩稿綋浜庝竴涓敱澶氫釜obj鏂囦歡緇勫悎鑰屾垚鐨刼bj鏂囦歡錛屽湪閾炬帴鍚庡叾鎵鏈変唬鐮佽鍔犺澆錛屼笉綆¢渶瑕佺殑榪樻槸涓嶉渶瑕佺殑銆?/span>
浼間箮鍙互寰楀嚭涓涓粨璁猴細
闈欐侀摼鎺ュ悗鐨勭▼搴忔瘮鍔ㄦ侀摼鎺ョ殑鎵鐢ㄥ瓨鍌ㄧ┖闂村ぇ錛屽洜涓烘墽琛岀▼搴忎腑鍖呭惈浜嗗簱涓唬鐮佹嫹璐濓紱
鑰屽姩鎬侀摼鎺ョ殑紼嬪簭姣旈潤鎬侀摼鎺ョ殑鎵鐢ㄧ殑榪愯絀洪棿澶э紝鍥犱負瀹冨皢涓嶉渶瑕佺殑浠g爜涔熷姞杞藉埌榪愯絀洪棿銆?/span>
閽堝涓婇潰鐨勭煡璇? 涓棶棰橈細
1錛?DLL鍜?LIB鏂囦歡蹇呴』闅忓簲鐢ㄧ▼搴忎竴璧峰彂琛岋紝鍚﹀垯搴旂敤紼嬪簭灝嗕細浜х敓閿欒銆?nbsp;
鎴戠殑絳旀錛歭ib搴旇涓嶉渶瑕佸惂銆?br />
2錛夊鏋滄槸鏌愪釜紼嬪簭涓皟鐢ㄤ簡涓涓姩鎬佸簱錛堥氳繃header鏂囦歡錛宭ib+dll鏉ヨ皟鐢級錛屽垯瀵瑰姩鎬佸簱鐨勬煇涓嚱鏁扮殑鍐呭淇敼浜嗭紝浣嗘帴鍙d笉鏀癸紝鍒欒皟鐢ㄦ鍔ㄦ佸簱鐨勭▼搴忛渶閲嶆柊緙栬瘧榪炴帴鍚楋紵濡傛灉鏄氳繃loadlibary鍔ㄦ佸姞杞斤紝闇瑕侀噸鏂扮紪璇戣繛鎺ュ悧錛?br />
鐩墠鏈夊緢澶氫笉鍚岀被鍨嬬殑鐗堟湰鎺у埗緋葷粺錛圴ersion Control System錛?VCS錛夈備竴浜沄CS錛屾瘮濡?a style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #003366; text-decoration: none; ">Subversion鍜?a style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #003366; text-decoration: none; ">CVS錛屼互涓ぎ浠撳簱錛坮epository錛変負涓績榪涜鏋舵瀯銆傛澶栵紝榪樻湁鍒嗗竷寮忕殑VCS錛圖istributed VCS錛孌VCS錛夛紝 Git 鍜?nbsp;Mercurial 鏄袱涓柊榪戝嚭鐜扮殑DVCS銆傜劧鑰岋紝鍦ㄤ笂榪頒袱縐嶇被鍨嬬殑鐜涓紝閫氬父浼氭湁涓涓?#8220;鎸囧畾鐨?#8221;涓ぎ浠撳簱銆傚搴斿湴錛屾瘮濡備竴涓猄ubversion鏈嶅姟鍣ㄦ垨鑰呬竴涓?a style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #003366; text-decoration: none; ">GitHub浠撳簱銆備笅闈細鍩轟簬榪欎釜鍦烘櫙榪涜鍥劇ず璇存槑銆傞偅涔堣鎴戜滑寮濮嬪惂銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
鍦ㄥ紑鍙戣呮嫹璐濆埌鏈満涔嬪墠錛屾湇鍔″櫒闇瑕佸垱寤轟竴涓粨搴撱傚垱寤哄垵濮嬩粨搴撲細鐢變簬浜у搧涓嶅悓鑰屾湁鎵宸埆銆備粠鐜板湪璧鳳紝浣犳墍瑕佺煡閬撶殑灝辨槸錛屽湪鏈嶅姟鍣ㄤ笂鏈変竴涓垵濮嬬┖闂淬傛垜鎶婅繖涓増鏈О浣滅増鏈?#8220;A”銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
鐜板湪錛屾瘡涓紑鍙戣咃紙寮鍙戣?鍜屽紑鍙戣?錛夐兘浼氭嫹璐濈増鏈?#8220;A”鍒頒粬浠湰鍦扮數鑴戙傚啀涓嬈″湴錛屼粠鏈嶅姟鍣ㄦ嫹璐濈殑榪囩▼浼氱敱浜庝駭鍝佷笉鍚岄噰鐢ㄧ殑鎶鏈細鏈夋墍宸埆銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
姣忎釜寮鍙戣呬細鍦ㄤ粬浠殑鏈湴鎷瘋礉涓婅繘琛屽紑鍙戙備粬浠殑鏈湴鎷瘋礉鍩轟簬鐗堟湰“A”銆傜劧鑰岋紝鐢變簬浠栦滑搴旇涓嶄細鍋氬悓鏍風殑寮鍙戯紝鍥犺屼粬浠殑鐗堟湰浼氭湁鎵宸埆銆傚洜姝わ紝浼氭湁2涓互涓婄殑鐗堟湰浼氬悓鏃惰鍒涘緩錛屾瘮濡傜増鏈?#8220;B”鍜岀増鏈?#8220;C”銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
寮鍙戣?棣栧厛瀹屾垚浜嗗ス鐨勫伐浣滃茍鎻愪氦鍒版湇鍔″櫒銆傛湇鍔″櫒涓婄殑褰撳墠鐗堟湰琚洿鏂版垚鐗堟湰“B”銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
寮鍙戣?鐜板湪瀹屾垚浜嗕粬鐨勫伐浣滃茍璇曞浘鎻愪氦鍒版湇鍔″櫒銆傜劧鑰岋紝榪欐槸鏈嶅姟鍣ㄥ憡鐭ヤ粬鍩轟簬寮鍙戠殑鐗堟湰宸茬粡鍙戠敓鏀瑰彉銆?strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">榪欎篃鏄負浠涔堥噰鍙栫増鏈帶鍒剁殑棣栬鍘熷洜涔嬩竴銆?/strong>榪欎釜鐗規ф槸瀵圭綉緇滃叡浜唬鐮佺劧鍚庣敱寮鍙戣呮墜鍔ㄦ洿鏂扮殑涓涓法瓚婂紡鍙戝睍錛岃繖紜繚浜嗕箣鍓嶇殑緙栬緫娌℃湁琚柊鐨勪慨鏀硅鐩栥?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
寮鍙戣?蹇呴』棣栧厛鑾峰緱鎵鏈夌増鏈?#8220;B”鐨勫彉鍖栵紝騫跺悎騫跺埌浠栫殑淇敼涓紝鐒跺悗鎵嶅彲浠ユ彁浜ゅ埌鏈嶅姟鍣ㄣ傝繖涓繃紼嬪惉璧鋒潵鏈変簺澶嶆潅銆傜劧鑰岋紝澶у鏁扮幇浠g殑鐗堟湰鎺у埗緋葷粺鍗佸垎楂樼駭錛岃兘澶熻嚜鍔ㄥ湪寮鍙戣呯殑鏈湴鎷瘋礉涓婂畬鎴愬悎騫躲傛湁鍑犵鎯呭喌浼氫駭鐢熷啿紿侊紙渚嬪錛氬紑鍙戣?鍜屽紑鍙戣?鍚屾椂淇敼浜嗗悓涓涓枃浠剁殑鍚屼竴琛岋級銆傝繖灝辨槸涓浜沄CS浜у搧姣斿叾浠栨洿楂樼駭鐨勫湴鏂廣備笉璁哄浣曞畬鎴愬悎騫訛紝鐜板湪寮鍙戣?鍦ㄤ粬浠殑鏈湴緋葷粺涓婂悓鏃舵販鍚堜簡鐗堟湰B鍜岀増鏈珻銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
鐜板湪寮鍙戣?鍙互鎻愪氦浠栫殑鐗堟湰鍒版湇鍔″櫒銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
榪欐槸涓涓増鏈帶鍒剁殑鍩虹銆傞氳繃娉ㄦ剰瑙傚療鍥句腑鏈嶅姟鍣ㄧ殑榪炵嚎鍙互鍙戠幇鐗堟湰鎺у埗鐨勫師鐞嗐傛湇鍔″櫒璁板綍浜嗘墍鏈夊厛鍓嶇殑鐗堟湰鍖呮嫭鍙戠敓鐨勫彉鍖栵紝浠涔堟椂鍊欏彂鐢熶互鍙婄敱璋佽繘琛屼慨鏀廣傚綋闇瑕佽繘琛屼唬鐮佸洖婧垨鑰呭紩鍏ュ叾浠朾ug鏃訛紝榪欎釜璁板綍鑳藉瑙i櫎鍥板銆?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />鎴戝笇鏈涙湰鏂囪兘澶熶負鐗堟湰鎺у埗緋葷粺鎻愪緵涓涓熀紜鐨勪粙緇嶃傚鏋滀綘鏈変換浣曠枒闂紝璇峰氨浣犻棶棰樺彂琛ㄨ瘎璁恒?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
鑻辨枃鍘熸枃錛?a style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #003366; text-decoration: none; ">greenmoonsoftware 緙栬瘧錛?a style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #003366; text-decoration: none; ">浼箰鍦ㄧ嚎 – 鍞愬挨鍗?/a>
#include <stdlib.h> void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) ); |
#include <stdlib.h> void *bsearch( const void *key, const void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) ); |
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
using namespace std;
void queen(int** array, int row, FILE* fp);
bool isAvailable(int** array, int y, int x);
bool isResult(int** array);
int main(int arg, char** argv) {
int** array;
// 鍒嗛厤絀洪棿
array = new int*[8];
for (int i = 0; i < 8; i++) {
array[i] = new int[8];
}
// 鍒濆鍖栫殗鍚庣姸鎬?/font>
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
array[i][j] = 0;
}
}
FILE* fp = fopen("data.txt", "w");
queen(array, 0, fp);
fclose(fp);
// 閲婃斁絀洪棿
for (int i = 0; i < 8; i++) {
delete[] array[i];
}
delete array;
array = NULL;
return 0;
}
void queen(int** array, int row, FILE* fp) {
static int size = 1;
if (row > 7) {
return;
}
for (int j = 0; j < 8; j++) {
// 濡傛灉鍚堟硶
if (isAvailable(array, row, j)) {
array[row][j] = 1;
// 褰撳墠浣嶇疆鍚堟硶錛岃祴鍊煎悗錛岃繘鍏ヤ笅涓琛?br style="line-height: 15px; "> queen(array, row + 1, fp);
// 濡傛灉閫鍥炴潵鍚庢槸緇撴灉錛屽垯鎵撳嵃鍑烘潵
if (isResult(array)) {
// 鎶婄粨鏋滃啓鍏ユ枃浠?br style="line-height: 15px; "> fputc('\n', fp);
fputs("***********************************", fp);
fprintf(fp, " %d ", size++);
fputs("***********************************", fp);
fputc('\n', fp);
for (int m = 0; m < 8; m++) {
for (int n = 0; n < 8; n++) {
if (array[m][n] == 1) {
fputc('#', fp);
fputc(' ', fp);
fputc(' ', fp);
} else {
fputc('O', fp);
fputc(' ', fp);
fputc(' ', fp);
}
}
fputc('\n', fp);
}
}
array[row][j] = 0;
}
}
}
bool isAvailable(int** array, int row, int column) { // 絎瑀ow琛岋紝column鍒?br style="line-height: 15px; "> int i, j;
// 媯鏌ow琛?/font>
for (i = 0; i < 8; i++) {
if (array[row][i] != 0) {
return false;
}
}
// 媯columnx鍒?/font>
for (j = 0; j < 8; j++) {
if (array[j][column] != 0) {
return false;
}
}
// 媯鏌ュ瑙掑悜宸︿笂
i = row;
j = column;
while (i >= 0 && j >= 0) {
if (array[i][j] != 0) {
return false;
}
i--;
j--;
}
// 媯鏌ュ瑙掑悜鍙充笂
i = row;
j = column;
while (i >= 0 && j < 8) {
if (array[i][j] != 0) {
return false;
}
i--;
j++;
}
// 媯鏌ュ瑙掑悜宸︿笅
i = row;
j = column;
while (i < 8 && j >= 0) {
if (array[i][j] != 0) {
return false;
}
i++;
j--;
}
// 媯鏌ュ瑙掑悜鍙充笅
i = row;
j = column;
while (i < 8 && j < 8) {
if (array[i][j] != 0) {
return false;
}
i++;
j++;
}
return true;
}
bool isResult(int** array) {
int size = 0; // 鐨囧悗涓暟
// 緇熻鐨囧悗涓暟
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (array[i][j] != 0) {
size++;
}
}
}
// 娌℃湁錛樹釜鐨囧悗錛岃鏄庝笉鏄粨鏋?/font>
// 鏈?涓殗鍚?鍥犱負姣忎釜鐨囧悗鐨勬斁緗兘鏄湪鍚堟硶浣嶇疆, 鎵浠ュ彧闇瑕佺畝鍗曠殑璁$畻鐨囧悗涓暟灝辯煡閬撴槸涓嶆槸緇撴灉.
if (size != 8) {
return false;
}
return true;
}
#include <stdio.h>
#include <math.h>
int main() {
double y;
int x, f, i;
/* 杈撳嚭姝g巹, 鍗曡皟鍖洪棿 x: [-pi/2, pi/2], y: [-1, 1] */
/* 瑕佸垎鎴愪袱涓儴鍒嗘潵璁$畻杈撳嚭 */
for (y = 1; y > 0; y -= 0.1) {
x = asin(y) * 10;
for (i = 1; i < x; ++i) printf(" ");
printf("*");
for (; i < 32 - x; ++i) printf(" ");
printf("*\n");
}
for (y = 0; y >= -1; y -= 0.1) {
x = asin(y) * 10; /* x鏄礋鍊?*/
for (i = 1; i < 34 - x; ++i) printf(" ");
printf("*");
for (; i < 66 + x; ++i) printf(" ");
printf("*\n");
}
printf("\n\n");
/* 杈撳嚭浣欑巹, 鍗曡皟鍖洪棿 x: [0, pi], y: [1, -1] */
for (y = 1; y >= -1; y -= 0.1) {
x = (int)(acos(y) * 10);
for (i = 0; i <= 64; ++i) {
if (i == x || i == 64 - x) {
printf("*");
} else {
printf(" ");
}
}
printf("\n");
}
}
I am in a different position with respect to this fix. I had installed cmake 2.8.2_3 before the Apple Java update. After the Apple Java update, the cmake upgrade from 2.8.2_3 to 2.8.2_4 failed saying that I needed to install Java from Apple, which was already installed. As far as I can tell, the Apple update to Java 1.6.0_22 did not properly update the header path. In the updated version the header path leads to a dead end. I was able to fix this by doing the following.
1) Create directory
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Headers
2) Copy entire contents of directory
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers
to directory
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Headers
After this fix the upgrade to cmake 2.8.2_4 worked. However, if the macports cmake could be made to look for the Java headers in /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers this would resolve an existing problem.
From: https://trac.macports.org/ticket/26934
5. 鏈緇堝ぇ鎴忔潵浜嗭紝瀹夎OpenCV: http://sunny.in.th/2010/04/27/installing-opencv-21-on-snow-leopard.html
Installing OpenCV 2.1 on Snow Leopard has become quite easy at least easier than 2.0. Version 2.1 can now be compiled as 64-bit library.
Before version 2.1 OpenCV used Carbon which is the old GUI interface for Mac OS. Carbon supports only 32-bit and has been deprecated by Apple. The new GUI interface for Mac OS is Cocoa. With Snow Leopard being a 64-bit kernel it would be nice if we could compile OpenCV as a 64-bit library and not not 32-bit just because of Carbon. Thanks to the OpenCV team they have added Cocoa support in version 2.1.
To install OpenCV check out the code from the svn repository and compile it.
$ svn co https://code.ros.org/svn/opencv/trunk/opencv
$ cd opencv
$ mkdir build
$ cd build
$ cmake ..
Configure the make by
$ ccmake .
If you want you can build the samples as well.
Press c
to configure, followed by g
to generate. Next build and install OpenCV by
$ make -j8
$ sudo make install
That’s it!!! Simple right.
If you want to use Python with OpenCV there’s a little more that needs to be done. By default OpenCV copies the shared object file required by the Python interface to /usr/local/lib/python2.6/site-packages/cv.so
which is not under Python path. Add the following line to your .bashrc
or .bash_profile
PYTHONPATH=/usr/local/lib/python2.6/site-packages/cv.so:$PYTHONPATH
Trying running some C
samples which are in /usr/local/share/opencv/samples/c/
. The Python samples at/usr/local/share/opencv/samples/python/
doesn’t work since they are based on the old SWIG-Python interface. Try running the sample Python code which is in the opencv
directory that was checked out from subversion. It’s insidesamples/python
.
short a=2000; int b; b=a; |
Here, the value of a has been promoted from short to int and we have not had to specify any type-casting operator. This is known as a standard conversion. Standard conversions affect fundamental data types, and allow conversions such as the conversions between numerical types (short to int, int to float, double to int...), to or from bool, and some pointer conversions. Some of these conversions may imply a loss of precision, which the compiler can signal with a warning. This can be avoided with an explicit conversion.
Implicit conversions also include constructor or operator conversions, which affect classes that include specific constructors or operator functions to perform conversions. For example:
class A {}; class B { public: B (A a) {} }; A a; B b=a; |
Here, a implicit conversion happened between objects of class A and class B, because B has a constructor that takes an object of class A as parameter. Therefore implicit conversions from A to B are allowed.
short a=2000; int b; b = (int) a; // c-like cast notation b = int (a); // functional notation |
The functionality of these explicit conversion operators is enough for most needs with fundamental data types. However, these operators can be applied indiscriminately on classes and pointers to classes, which can lead to code that while being syntactically correct can cause runtime errors. For example, the following code is syntactically correct:
// class type-casting #include <iostream> using namespace std; class CDummy { float i,j; }; class CAddition { int x,y; public: CAddition (int a, int b) { x=a; y=b; } int result() { return x+y;} }; int main () { CDummy d; CAddition * padd; padd = (CAddition*) &d; cout << padd->result(); return 0; } |
The program declares a pointer to CAddition, but then it assigns to it a reference to an object of another incompatible type using explicit type-casting:
padd = (CAddition*) &d; |
Traditional explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to. The subsequent call to member result will produce either a run-time error or a unexpected result.
In order to control these types of conversions between classes, we have four specific casting operators: dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed between angle-brackets (<>) and immediately after, the expression to be converted between parentheses.
dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)
The traditional type-casting equivalents to these expressions would be:
(new_type) expression
new_type (expression)
but each one with its own special characteristics:
dynamic_cast can be used only with pointers and references to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.
Therefore, dynamic_cast is always successful when we cast a class to one of its base classes:
class CBase { }; class CDerived: public CBase { }; CBase b; CBase* pb; CDerived d; CDerived* pd; pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived |
The second conversion in this piece of code would produce a compilation error since base-to-derived conversions are not allowed with dynamic_cast unless the base class is polymorphic.
When a class is polymorphic, dynamic_cast performs a special checking during runtime to ensure that the expression yields a valid complete object of the requested class:
// dynamic_cast #include <iostream> #include <exception> using namespace std; class CBase { virtual void dummy() {} }; class CDerived: public CBase { int a; }; int main () { try { CBase * pba = new CDerived; CBase * pbb = new CBase; CDerived * pd; pd = dynamic_cast<CDerived*>(pba); if (pd==0) cout << "Null pointer on first type-cast" << endl; pd = dynamic_cast<CDerived*>(pbb); if (pd==0) cout << "Null pointer on second type-cast" << endl; } catch (exception& e) {cout << "Exception: " << e.what();} return 0; } | Null pointer on second type-cast |
Compatibility note: dynamic_cast requires the Run-Time Type Information (RTTI) to keep track of dynamic types. Some compilers support this feature as an option which is disabled by default. This must be enabled for runtime type checking using dynamic_cast to work properly. |
The code tries to perform two dynamic casts from pointer objects of type CBase* (pba and pbb) to a pointer object of type CDerived*, but only the first one is successful. Notice their respective initializations:
CBase * pba = new CDerived; CBase * pbb = new CBase; |
Even though both are pointers of type CBase*, pba points to an object of type CDerived, while pbb points to an object of type CBase. Thus, when their respective type-castings are performed using dynamic_cast, pba is pointing to a full object of class CDerived, whereas pbb is pointing to an object of class CBase, which is an incomplete object of class CDerived.
When dynamic_cast cannot cast a pointer because it is not a complete object of the required class -as in the second conversion in the previous example- it returns a null pointer to indicate the failure. If dynamic_cast is used to convert to a reference type and the conversion is not possible, an exception of type bad_cast is thrown instead.
dynamic_cast can also cast null pointers even between pointers to unrelated classes, and can also cast pointers of any type to void pointers (void*).
class CBase {}; class CDerived: public CBase {}; CBase * a = new CBase; CDerived * b = static_cast<CDerived*>(a); |
This would be valid, although b would point to an incomplete object of the class and could lead to runtime errors if dereferenced.
static_cast can also be used to perform any other non-pointer conversion that could also be performed implicitly, like for example standard conversion between fundamental types:
double d=3.14159265; int i = static_cast<int>(d); |
Or any conversion between classes with explicit constructors or operator functions as described in "implicit conversions" above.
It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is platform-specific. The only guarantee is that a pointer cast to an integer type large enough to fully contain it, is granted to be able to be cast back to a valid pointer.
The conversions that can be performed by reinterpret_cast but not by static_cast have no specific uses in C++ are low-level operations, whose interpretation results in code which is generally system-specific, and thus non-portable. For example:
class A {}; class B {}; A * a = new A; B * b = reinterpret_cast<B*>(a); |
This is valid C++ code, although it does not make much sense, since now we have a pointer that points to an object of an incompatible class, and thus dereferencing it is unsafe.
// const_cast #include <iostream> using namespace std; void print (char * str) { cout << str << endl; } int main () { const char * c = "sample text"; print ( const_cast<char *> (c) ); return 0; } | sample text |
typeid (expression)
This operator returns a reference to a constant object of type type_info that is defined in the standard header file <typeinfo>. This returned value can be compared with another one using operators == and != or can serve to obtain a null-terminated character sequence representing the data type or class name by using its name() member.
// typeid #include <iostream> #include <typeinfo> using namespace std; int main () { int * a,b; a=0; b=0; if (typeid(a) != typeid(b)) { cout << "a and b are of different types:\n"; cout << "a is: " << typeid(a).name() << '\n'; cout << "b is: " << typeid(b).name() << '\n'; } return 0; } | a and b are of different types: a is: int * b is: int |
When typeid is applied to classes typeid uses the RTTI to keep track of the type of dynamic objects. When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object:
// typeid, polymorphic class #include <iostream> #include <typeinfo> #include <exception> using namespace std; class CBase { virtual void f(){} }; class CDerived : public CBase {}; int main () { try { CBase* a = new CBase; CBase* b = new CDerived; cout << "a is: " << typeid(a).name() << '\n'; cout << "b is: " << typeid(b).name() << '\n'; cout << "*a is: " << typeid(*a).name() << '\n'; cout << "*b is: " << typeid(*b).name() << '\n'; } catch (exception& e) { cout << "Exception: " << e.what() << endl; } return 0; } | a is: class CBase * b is: class CBase * *a is: class CBase *b is: class CDerived |
Notice how the type that typeid considers for pointers is the pointer type itself (both a and b are of type class CBase *). However, when typeid is applied to objects (like *a and *b) typeid yields their dynamic type (i.e. the type of their most derived complete object: 鐪熷疄鐨勭被鍨嬶紝鍗充嬌瀛愮被瀵硅薄浣跨敤鐨勬槸鐖剁被鐨勬寚閽堬紝浣嗚繑鍥炵殑瀛愮被鐨勪俊鎭?.
If the type typeid evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value, typeid throws a bad_typeid exception.