2009-06-05 40 views
22

Tôi đang cố sử dụng các hàm thành viên nội tuyến của một lớp cụ thể. Ví dụ khai báo hàm và thực hiện mà không cần nội tuyến là như vậy:lỗi liên kết hàm nội tuyến

trong file header:

int GetTplLSize(); 

trong file cpp:

int NeedleUSsim::GetTplLSize() 
{ 
    return sampleDim[1]; 
} 

Đối với một số lý do nếu tôi đặt " nội tuyến "từ khóa trong một trong hai việc thực hiện và khai báo, cũng như ở cả hai nơi, tôi nhận được lỗi liên kết như được hiển thị:

 
Creating library C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.x and object C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.exp 
mexfunction.obj : error LNK2019: unresolved external symbol "public: int __thiscall NeedleUSsim::GetTplLSize(void)" ([email protected]@@QAEHXZ) referenced in function _mexFunction 
mexfunction.mexw32 : fatal error LNK1120: 1 unresolved externals 

    C:\PROGRA~1\MATLAB\R2008B\BIN\MEX.PL: Error: Link of 'mexfunction.mexw32' failed. 

Cần phải làm gì để loại bỏ lỗi này (tức là Tôi đang làm gì sai trong việc thực hiện các chức năng thành viên nội tuyến này)?

Trả lời

23

Bạn cần đặt định nghĩa hàm vào tiêu đề sau đó. Cách đơn giản nhất để gợi ý trình biên dịch để inline là bao gồm phương pháp cơ thể trong khai báo lớp như:


class NeedleUSsim 
{ 
    // ... 
    int GetTplLSize() const { return sampleDim[1]; } 
    // ... 
}; 

hoặc, nếu bạn nhấn mạnh vào tờ khai riêng và định nghĩa:


class NeedleUSsim 
{ 
    // ... 
    int GetTplLSize() const; 
    // ... 
}; 

inline int NeedleUSsim::GetTplLSize() const 
{ return sampleDim[1]; } 

Định nghĩa phải là hiển thị trong mỗi đơn vị dịch sử dụng phương pháp đó.

+0

Đây có phải là cách duy nhất không? (Tôi muốn tách riêng việc khai báo và triển khai một cách riêng biệt vì các lý do dễ đọc) – stanigator

+1

Về cơ bản là có. Trình biên dịch phải biết phần thân của hàm trong khi biên dịch các cuộc gọi đến hàm đó, do đó cơ thể phải nằm trong tệp tiêu đề được bao gồm. Tuy nhiên, bạn vẫn có thể khai báo hàm trong khai báo lớp và thêm việc triển khai thực hiện ở vị trí sau trong tệp tiêu đề. – Hans

+0

Tôi hiểu. Tôi đoán tôi sẽ phải sống bằng cách viết mã theo cách này. Cảm ơn lời khuyên. – stanigator

2

Nếu bạn có hàm nội dòng, bạn nên đặt định nghĩa trong tệp tiêu đề.

+0

Tôi đã thử đặt từ khóa nội tuyến vào các định nghĩa trong tệp tiêu đề và tôi vẫn nhận được cùng một lỗi trình liên kết. – stanigator

+2

Không chỉ từ khóa nội tuyến, toàn bộ định nghĩa sẽ xuất hiện trong tệp tiêu đề. Vì vậy, hãy di chuyển nó từ tệp .cpp của bạn vào tệp .h của bạn. – ChrisInEdmonton

+1

Định nghĩa, không khai báo. –

17

từ C++ FAQ Lite

Nếu bạn đặt định nghĩa chức năng inline của vào một tập tin cpp, và nếu nó được gọi từ một số tập tin cpp khác, bạn sẽ nhận được một "chưa được giải quyết bên ngoài " lỗi từ trình liên kết.

How do you tell the compiler to make a member function inline?

+0

thật không may, như tôi chỉ phát hiện ra một cách khó khăn, đây không phải là trường hợp trong MSVC 2013 và 2015. Tôi đã có một nội tuyến trong tệp CPP (trong thư viện) và mã của nó được gọi từ một số mã nguồn CPP hoàn toàn khác có dòng nội tuyến riêng có cùng tên (nhưng mã hơi khác, do đó kết quả đã phá vỡ các thử nghiệm). Tôi cho rằng một lỗi trong môi trường phát triển đó. Khó tìm... – chksr

3

Như những người khác đã chỉ ra, bạn cần phải di chuyển các định nghĩa của hàm inlined đến tập tin tiêu đề, như vậy:

class NeedleUSsim 
{ 
    // ... 
    inline int GetTplLSize() { return sampleDim[1]; } 
    // ... 
}; 

Lý do cho điều này là các trình biên dịch cần phải biết mã nào là nội dòng khi nó thấy một cuộc gọi đến hàm nội tuyến. Nếu bạn để định nghĩa hàm trong tệp .cpp cho lớp NeedleUSsim, mã mà trình biên dịch tạo ra cho nó sẽ bị mắc kẹt trong tệp đối tượng NeedleUSsim. Khi trình biên dịch chỉ đọc mã nguồn — nó không bao giờ nhìn vào tập tin đối tượng của lớp khác — nó chỉ đơn giản là không có cách nào để biết với mã nào để thay thế một cuộc gọi khi nó biên dịch một tệp .cpp khác.

0

Xem Inline Guard Macro idiom. Điều này ít nhất sẽ cho phép bạn tách biệt, mặc dù hơi, mã từ tờ khai. Nó cũng cho phép bạn chuyển đổi nội tuyến chức năng thông qua một define.

Các vấn đề liên quan