Có phải là một ý tưởng tốt để cung cấp chữ ký chức năng khác nhau làm điều tương tự?


23

Đây là một lớp C ++ được xây dựng với ba giá trị.

class Foo{

    //Constructor
    Foo(std::string, int, char);

private:
    std::string foo;
    char bar;
    int baz;
};

Tất cả các loại tham số là khác nhau.
Tôi có thể quá tải hàm tạo để thứ tự không thành vấn đề.

class Foo{

    //Constructors
    Foo(std::string, char, int);
    Foo(std::string, int, char);
    Foo(char, int, std::string);
    Foo(char, std::string, int);
    Foo(int, std::string, char);
    Foo(int, char, std::string);


private:
    std::string foo;
    char bar;
    int baz;
};

Nhưng đó có phải là một ý tưởng tốt?
Tôi bắt đầu làm điều đó bởi vì tôi biết những gì một lớp / chức năng cần thiết;
Tôi đã không luôn nhớ thứ tự nó đã đưa họ vào.


Tôi đã giả định rằng trình biên dịch tối ưu hóa điều này như thể tôi đã gọi cùng một hàm tạo.

//compiler will implement this with the same code? 
//maybe not.. I could call a function to get a parameter, 
//and that function could change the state of the program, before calling
//a function to get another parameter and the compiler would have to
//implement both
Foo foo1("hello",1,'a');
Foo foo2('z',0,"world");

Ý kiến ​​của bạn về việc quá tải một chức năng để thứ tự không thành vấn đề?


Ngoài ra, nếu tôi đang viết một số chức năng tiện ích,
bạn có nên cung cấp các tên hàm khác nhau làm cùng một việc không?

ví dụ.

void Do_Foo();
void DoFoo();
void do_foo();
//etc..

Tôi không thường thấy hai quy ước này nhưng tương tự nhau.
Tôi nên phá vỡ hoặc nắm lấy thói quen?


1
Người ta chỉ nên dành nỗ lực cung cấp cho nhiều cách để thể hiện một cái gì đó nếu mỗi cách được cung cấp rõ ràng trong một số trường hợp sẽ vượt trội rõ ràng và rõ ràng hơn bất kỳ cách nào khác. Điều đó không có nghĩa là người ta thường phải nỗ lực để đảm bảo rằng một cái gì đó chỉ có thể được viết dưới một hình thức chính tắc, nhưng sẽ không có ý nghĩa gì khi đưa ra nỗ lực cho phép một cái gì đó được chỉ định theo cách nào đó không phải là tốt nhất.
supercat

Đây là một bản sao của câu hỏi của tôi ở đây (bây giờ tôi đồng ý rằng đó là một ý tưởng tồi).
rẽ trái

Câu trả lời:


93

Tôi có thể quá tải hàm tạo để thứ tự [của các tham số] không thành vấn đề ... Nhưng đó có phải là một ý tưởng tốt không?

Không.

Có quá tải nhà xây dựng khác nhau sẽ có tác động ngược lại với những gì bạn đang dự định. Lập trình viên đến sau khi bạn mong đợi các tình trạng quá tải khác nhau có hành vi khác nhau và sẽ hỏi: "Loại hành vi khác nhau nào được thể hiện bởi mỗi tình trạng quá tải này?

Hầu hết các lập trình viên mong đợi kỷ luật có các tham số phương thức theo thứ tự được xác định trước và các công cụ như IntelliSense sẽ cho họ biết thứ tự dự kiến ​​của các tham số khi họ nhập chúng.


Có nhiều tên hàm làm cùng một việc là cùng một vấn đề; lập trình viên mong đợi các biến thể có hành vi khác nhau. Xin vui lòng một chức năng hoặc phương thức cho mỗi hành vi và chỉ áp dụng một mẫu đặt tên nhất quán.


14
rất nhiều phiếu bầu. Tôi sẽ dừng lại ngay lập tức. cảm ơn bạn.
Trevor Hickey

8
Ngoài ra, bạn không thể đặt tên các nhà xây dựng khác nhau để giải thích mục đích của mình, người đọc phải suy luận nó từ các tham số. Quá tải hàm tạo theo cách này làm cho nó khó hiểu hơn nhiều.
Zachary Yates

3
"Có nhiều tên chức năng đó làm điều tương tự ..." - trong một thời gian 'tốt', nhìn vào Ruby lớp chuỗi Hash Mảng file .

+1. Bạn đang làm việc với các nhà phát triển / lập trình viên. Ý tưởng của Microsoft về "người dùng là khỉ", không hoạt động ở đây.
Manoj R

1
@ZacharyYates Thiếu "tên nhà xây dựng" có thể được xử lý bằng cách hiển thị phương thức xây dựng tĩnh thay thế. Đây là một cách thực hành chuẩn trong Java, mặc dù không quá nhiều trong C ++.
Xion

14

Đôi khi hỗ trợ đi lại giữa các đối số là cần thiết. Ví dụ:

double operator *(int, double);
double operator *(double, int);

Chúng tôi không muốn nhân một intdoubleđể tính toán một cái gì đó khác nếu toán hạng bị đảo ngược. Chúng tôi cũng không muốn buộc các lập trình viên nhớ rằng khi nhân ints và doubles, doublebên trái!

Không thành vấn đề vì đây là một nhà điều hành vì điều tương tự cũng xảy ra:

footype plus(const footype &, const bartype &);
footype plus(const bartype &, const footype &);

Nó thực sự phụ thuộc vào các loại chức năng. Trong khi hầu hết các lập trình viên có thể muốn hỗ trợ tính giao hoán trong các thư viện số học, họ không nhất thiết muốn, giả sử, một hàm thư viện I / O để hỗ trợ tất cả các lệnh đối số có thể.

Mối quan tâm có lẽ xoay quanh việc lồng dự kiến ​​trong đó các lệnh gọi hàm sẽ được tham gia. Tính linh hoạt trong các toán tử số học cho phép chúng ta thay đổi cấu trúc tổng thể của cây cú pháp để làm rõ biểu thức tổng thể: nhóm các thuật ngữ tương tự với nhau và như vậy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.