2008-08-21 9 views
58

VC++ làm cho các hàm được thực hiện trong các hàm nội tuyến khai báo lớp.Trong C++ có thể constructor và destructor là inline function?

Nếu tôi khai báo một lớp Foo như sau, thì các hàm nội tuyến CONSTRUCTOR và DESTRUCTOR là gì?

class Foo 
{ 
    int* p; 
public: 
    Foo() { p = new char[0x00100000]; } 
    ~Foo() { delete [] p; } 
}; 

{ 
    Foo f; 
    (f); 
} 

Trả lời

57

Xác định cơ thể của các nhà xây dựng bên trong lớp có cùng tác dụng của việc đặt chức năng bên ngoài lớp với từ khóa "inline".

Trong cả hai trường hợp, đó là gợi ý cho trình biên dịch. Một hàm "inline" không nhất thiết có nghĩa là hàm sẽ được inlined. Điều đó phụ thuộc vào độ phức tạp của hàm và các quy tắc khác.

+20

Đó không chỉ là gợi ý: nội tuyến cho phép bạn xác định cùng một chức năng trong nhiều đơn vị dịch. Đây là điều kiện tiên quyết để nội tuyến hóa chức năng tại một trang web gọi (không có tối ưu hóa thời gian liên kết), là nơi từ khóa nhận được tên của nó. –

+3

@FredNurk i hoàn toàn đồng ý với bạn - Tuy nhiên Stroustrup mình (Thiết kế và tiến hóa của C++) tham chiếu đến 'inline' như là một 'gợi ý' cho trình biên dịch –

+0

Như đã nói ở trên, câu trả lời này đã lỗi thời. [Ở đây] (https://stackoverflow.com/a/44247740/509868) là một câu trả lời cập nhật hơn cho một câu hỏi tương tự. – anatolyg

2

Đặt định nghĩa hàm trong nội dung lớp tương đương để đánh dấu hàm bằng từ khóa nội tuyến. Điều đó có nghĩa là chức năng có thể hoặc không thể được biên dịch bởi trình biên dịch. Vì vậy, tôi đoán câu trả lời tốt nhất sẽ là "có thể"?

25

Câu trả lời ngắn gọn là có. Bất kỳ hàm nào cũng có thể được khai báo nội tuyến và việc đặt thân hàm trong định nghĩa lớp là một cách để thực hiện điều đó. Bạn cũng có thể thực hiện:

class Foo 
{ 
    int* p; 
public: 
    Foo(); 
    ~Foo(); 
}; 

inline Foo::Foo() 
{ 
    p = new char[0x00100000]; 
} 

inline Foo::~Foo() 
{ 
    delete [] p; 
} 

Tuy nhiên, tùy thuộc vào trình biên dịch nếu nó thực sự thực hiện chức năng. VC++ khá nhiều bỏ qua yêu cầu của bạn cho nội tuyến. Nó sẽ chỉ inline một chức năng nếu nó nghĩ rằng đó là một ý tưởng tốt. Các phiên bản gần đây của trình biên dịch cũng sẽ nội tuyến những thứ nằm trong các tệp .obj riêng biệt và không được khai báo nội tuyến (ví dụ: từ mã trong các tệp .cpp khác nhau) nếu bạn sử dụng link time code generation.

Bạn có thể sử dụng từ khóa __forceinline để cho trình biên dịch biết rằng bạn thực sự thực sự có ý nghĩa khi bạn nói "inline this function", nhưng nó không phải là giá trị của nó. Trong nhiều trường hợp, trình biên dịch thực sự không biết rõ nhất.

1

Cùng một mức độ mà chúng tôi có thể thực hiện bất kỳ chức năng nào khác trong dòng, có.

1

Để nội tuyến hay không chủ yếu được quyết định bởi trình biên dịch của bạn. Nội tuyến trong mã chỉ gợi ý cho trình biên dịch.
Một quy tắc mà bạn có thể dựa vào đó là các chức năng ảo sẽ không bao giờ được gạch chân. Nếu lớp cơ sở của bạn có constructor ảo/destructor thì có lẽ bạn sẽ không bao giờ được inlined.

+0

btw, các hàm thành viên ảo (bao gồm cả các destructor ảo) có thể được gạch chân nếu trình biên dịch biết loại (hoàn chỉnh) của đối tượng đang bị hủy. –