2016-11-24 32 views
8

Tôi rất mới để C++, và khi tôi đang cố gắng tìm hiểu các hàm bạn bè, tôi thấy từ friend description on Cppreference rằng:Thành viên từ hàm bạn bè luôn là inline

2) (chỉ được phép trong định nghĩa lớp phi địa phương) Xác định một hàm không phải là thành viên, và làm cho nó trở thành một người bạn của lớp này cùng một lúc. Hàm không phải thành viên đó luôn là nội tuyến.

class X { 
    int a; 
    friend void friend_set(X& p, int i) { 
    p.a = i; // this is a non-member function 
    } 
    public: 
    void member_set(int i) { 
     a = i; // this is a member function 
    } 
}; 

Điều này có nghĩa rằng tất cả các chức năng bạn luôn phải inline? Trong một từ khác, các hàm của bạn bè có được định nghĩa hoàn toàn bên trong lớp không?

Tuy nhiên, tôi cũng tìm thấy một trường hợp mà các chức năng bạn được định nghĩa bên ngoài lớp từ Cplusplus

// friend functions 
#include <iostream> 
using namespace std; 
class Rectangle { 
    int width, height; 
    public: 
    Rectangle() {} 
    Rectangle (int x, int y) : width(x), height(y) {} 
    int area() {return width * height;} 
    friend Rectangle duplicate (const Rectangle&); 
}; 
Rectangle duplicate (const Rectangle& param) 
{ 
    Rectangle res; 
    res.width = param.width*2; 
    res.height = param.height*2; 
    return res; 
} 

Tôi thực sự bối rối bởi cuộc xung đột này. Hiểu biết của tôi về nội dòng có sai không? "a nonmember friend function defined inside the class is automatically inline" có nghĩa là gì?

+3

"được định nghĩa bên trong lớp" là các từ khóa ở đây. Hàm friend * được định nghĩa bên trong lớp * là nội dòng. Điều đó không có nghĩa là * tất cả * chức năng của bạn bè đều là nội dòng. Ví dụ thứ hai của bạn rõ ràng cho thấy một chức năng bạn bè được định nghĩa * bên ngoài * lớp. Nó không phải là nội tuyến. – AnT

+1

Bạn trích cú pháp 2 từ cppreference và sau đó bạn hỏi "Điều này có nghĩa là tất cả các hàm của bạn bè luôn phải là nội tuyến?" Không: một ví dụ ngược được đưa ra trong cú pháp ngay lập tức trước 1. –

Trả lời

11

mọi chức năng được xác định bên trong một lớp (thành viên hoặc bạn không phải thành viên) luôn hoàn toàn nội tuyến. Đó là vì các định nghĩa lớp thường nằm trong các tệp tiêu đề và bạn không muốn bất kỳ định nghĩa hàm không nội tuyến nào trong tệp tiêu đề (có hàm không phải nội tuyến trong tiêu đề dẫn đến nhiều định nghĩa nếu tiêu đề đượC#bao gồm nhiều hơn một tệp nguồn).

Nếu bạn muốn một hàm không phải là nội dòng, bạn cần phải xác định hàm đó bên ngoài định nghĩa lớp. Nếu thành viên hoặc bạn bè của bạn vẫn cần phải khai báo trong lớp học, vì các thành viên và bạn bè phải được khai báo trong lớp học. Bạn chỉ không muốn nó được định nghĩa trong lớp.

này tất cả được vào sự khác biệt giữa một định nghĩa khai trong C++ - họ là hai thứ riêng biệt, mặc dù tất cả các định nghĩa cũng là ngầm tuyên bố, không phải mọi tuyên bố là một định nghĩa. Kết quả là, khi spec nói 'khai báo' nó thường có nghĩa là 'khai báo không phải là định nghĩa'

+0

Điều đó thực sự hữu ích. Cảm ơn bạn! –

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