標籤:

c++ 內聯成員函數問題?

在c++primer第五版中照書上的例子在vs2013中用inline關鍵字修飾成員函數,無論是在類的聲明處,還是在類的外部定義處說明inline都會發生下面的這種錯誤

這個是該成員函數的類內部聲明

pos 是std::string::size_type的類型別名

這個是外部定義

不止這個成員函數,只要是這個類的成員函數一使用inline關鍵字修飾就會發生和上面一樣的錯誤,這個到底是怎麼回事?

補充一下----------------------------------------------------

聲明和定義一個在.h文件中,一個在.cpp文件中


首先inline是實現修飾符,而非聲明修飾符,所以應該用於實現部分的修飾(你也可以放置inline在聲明,但是沒有必要),我相信C++ Primer應該解釋的很清楚了。

那麼為什麼不能screen.h聲明函數move,screen.cpp實現move呢?因為inline的代碼是直接展開插入到被調用的地方,而非如普通函數的調用一樣,需要發生棧操作。即會先去執行被調用函數,再轉回來繼續執行主調函數。那麼,這個時候,你要麼在main.cpp也如同x.cpp一樣再次inline實現一次這個函數,要麼你就乾脆只在x.h的class body裡面實現了,當然如果你和我一樣有「代碼潔癖」的話,可以像我一樣先在class裡面聲明,再在class body外面實現:LLVMPascalCompiler/scanner.h at master · FrozenGene/LLVMPascalCompiler · GitHub

其實我覺得inline現在蠻雞肋的了,編譯器已經進化到今天這個地步了,我認為完全可以交給編譯器自己去決定是否inline(因為即使你給了inline,也只是給編譯器提醒可以inline,最後inline與否還是需要編譯器自己來決定),或許某一天inline將會和register關鍵字一樣退出舞台吧。


inline 函數 跟 main 不在一個編譯單元


一模一樣的問題(之一):

c++ - Linker error when inlining function from cpp file

個人理解,簡單來說是inline的要求。inline要求函數不被鏈接(至少是不像普通函數那樣鏈接),compiler在編譯每個cpp的時候都必須找得到函數的定義才能完成編譯。

另外,可以說現在的inline關鍵字已經完全和是否真的內聯沒關係了。 @藍色回答中提到「直接展開插入」,但實際上有時候也並非如此。無論是標準上還是實際操作上,都已經確實是「完全可以交給編譯器自己去決定是否inline」。


剛好遇到這個問題,看到 樓上的專業的解答,很滿意,加深一下自己的認識水平了:

想要在類外實現通過關鍵字inline實現內聯函數,要想編譯通過,有以下3種方式:

1、使用系統默認內聯,直接在頭文件類內實現;

shape.h文件:

class CShape

{

public:

CShape(void);

~CShape(void);

void draw() { cout&<&<"haahh"&<&};

2、在頭文件中類外加關鍵字inline實現,必須在頭文件中:

如:

shape.h文件:

class CShape

{

public:

CShape(void);

~CShape(void);

void draw();

};

inline void CShape::draw()

{

cout&<&<"haahh"&<&}

3、在main方法所在cpp文件內通過加關鍵字inline實現:

#include &

#include "test.h"

#include "shape.h"

inline void CShape::draw()

{

cout&<&<"haahh"&<&}

int main(int argc, char* argv[])

{

CShape * shape=new CShape();

shape-&>draw();

return 0;

}


把函數聲明放在.h文件下就可以解決了


記得C++primer裡面講了inline成員函數名自動具有static屬性吧


推薦閱讀:

如何理解c++primer中關於auto的說明?
新手如何閱讀《C++ Primer》?
string頭文件和string.h頭文件是一樣的?
為什麼c++要「在頭文件中聲明,在源文件中定義」?

TAG:C | CPrimer |