2016-09-25 15 views
8

Trước tiên, tôi KHÔNG nói về C++ 11 constructor chaining aka delegation constructor.Chức năng thành viên gọi chuỗi tắt một hàm tạo của một đối tượng được đặt tên

Các hàm thành viên của lớp có thể trả về tham chiếu cho chính nó (lớp) để các cuộc gọi chức năng có thể bị xích. (Chẳng hạn như cách nhà điều hành cúp < < hoạt động để cho phép các cuộc gọi chuỗi.)

Khi khởi tạo một đối tượng ẩn danh, các cuộc gọi chuỗi đó có thể xảy ra ngoài hàm tạo.

Có thể thực hiện các cuộc gọi chuỗi từ một hàm tạo của đối tượng được đặt tên không? Các dòng cho "foo a" và "foo b" bên dưới không biên dịch, vì vậy tôi tự hỏi nếu có một cú pháp khác.

#include <iostream> 
using namespace std; 

class foo { 
    public: 
     foo(int x) : val{x} { }; 
     foo& inc() { ++val; return *this; } 
     int getVal() { return val; }; 
    private: 
     int val; 
}; 

int main() { 
    cout << foo(1).inc().getVal() << endl; // prints 2 
    cout << foo{2}.inc().inc().inc().inc().getVal() << endl; // prints 6 
    foo a(3).inc(); // error: expected ‘,’ or ‘;’ before ‘.’ token 
    foo b{4}.inc(); // error: expected ‘,’ or ‘;’ before ‘.’ token 
    cout << a.getVal() << endl; 
    cout << b.getVal() << endl; 
} 
+3

cơ bản "không". 'foo (1)' là một biểu thức, 'foo a (3)' không phải là một biểu thức. Bạn sẽ phải viết 'foo a (3); a.inc(); ' –

Trả lời

2

Bạn có thể có được một hiệu ứng tương tự rằng chuỗi khởi tạo:

foo c = foo{5}.inc().inc(); 

Đáng ngạc nhiên, trình biên dịch của tôi được tối ưu hóa đến một hằng số, do đó không phải là một hình phạt hiệu suất.

2

Tôi nghĩ đây là một trong những ưu điểm của kiểu dáng Almost Always Auto. Nếu bạn đang ở trong thói quen viết:

auto a = foo{3}; 

sau đó bạn có thể gọi chuỗi mà không mâu thuẫn:

auto a = foo{3}.inc(); 
Các vấn đề liên quan