2008-10-29 33 views
11

Tôi tự hỏi liệu có thể thêm các phương thức trong chương trình chính vào một lớp hiện có được xác định trong tệp tiêu đề hay không. Ví dụ: Có class CFun định nghĩa trong file CFun.hpp, nhưng trong party.cpp chúng tôi muốn thêm một phương pháp void hello() {cout << "hello" << endl;}; mà không cần chỉnh sửa CFun.hppC++ thêm phương thức vào lớp được xác định trong tệp tiêu đề

Rõ ràng (không may) xây dựng:

#include "CFun.hpp" 

class CFun 
{ 
    public: 
    void hello() {cout << "hello" << endl;}; 
}; 

không hoạt động trở lại một lỗi Multiple declaration for 'CFun'

Có thể làm cho nó hoạt động mà không cần thừa kế lớp không?

Trả lời

9

Không, nhưng bạn có thể thêm một phương pháp mà phải mất một tài liệu tham khảo/con trỏ đến một lớp CFun - bạn chỉ sẽ không có quyền truy cập vào dữ liệu cá nhân:

void Hello(CFun &fun) 
{ 
    cout << "hello" << endl; 
} 

Đây có lẽ là tốt nhất bạn sẽ có có thể làm được. Như đã được chỉ ra bởi litb - chức năng này phải ở trong cùng một không gian tên như CFun. May mắn thay, không gian tên, không giống như các lớp, có thể được thêm vào ở nhiều nơi.

+1

bạn nên nói cho anh ta những chức năng cần phải được trong không gian tên tương tự như lớp. nếu không chỉ cần gọi Hello (some_cfun); sẽ không tìm thấy Hello. bạn sẽ phải viết foo :: Hello (some_cfun); sau đó (ADT sẽ không hoạt động sau đó) –

0

Không phải với kiến ​​thức của tôi. Mặc dù, bạn có thể thực hiện một số loại lắp ráp và thực hiện một giải pháp không gian tên-y.

3

Không, điều đó là không thể. Chỉ có thể có một định nghĩa về bất kỳ lớp cụ thể nào, và nó phải là một định nghĩa hoàn chỉnh, có nghĩa là bạn không thể có các định nghĩa từng phần ở các vị trí khác nhau, thêm các thành viên vào lớp.

Nếu bạn cần thêm hàm thành viên vào một lớp, bạn phải thay đổi định nghĩa lớp (chỉnh sửa CFun.hpp) hoặc lấy một lớp mới từ CFun và đặt hello() tại đó.

0

Sau khi nghĩ về nó, bạn có thể làm điều gì đó khủng khiếp: Tìm một số chức năng trong CFun có kiểu trả về mà bạn muốn và chỉ đề cập một lần trong toàn bộ tiêu đề. Giả sử void GoodBye().

Bây giờ, tạo một CFunWrapper.hpp tập tin với nội dung này:

#define GoodBye() Hello() { cout << "hello" << endl; } void GoodBye() 
#include "CFun.hpp" 
#undef GoodBye 

Sau đó, chỉ bao giờ bao gồm CFunWrapper.hpp thay vì CFun.hpp.

Nhưng đừng làm điều này, trừ khi có một số lý do thực sự tốt để làm như vậy. Nó rất dễ bị phá vỡ, và thậm chí không thể, tùy thuộc vào nội dung của CFun.hpp.

+0

Làm điều này cũng giống như chỉ sửa đổi CFun.hpp. Nó khá khó khăn để nghĩ về một tình huống mà điều này sẽ làm việc, nhưng bạn không thể chỉ thay đổi tập tin tiêu đề. Tôi đoán nó có thể được trên một ROFS. –

2

Tương tự gần nhất với loại cấu trúc đó (thêm chức năng cho các lớp được xác định trước) trong C++ là mẫu Decorator. Nó không chính xác những gì bạn đang sau, nhưng nó có thể cho phép bạn làm những gì bạn cần.

0
class Party : class CFun 

(party.cpp của bạn)

thừa hưởng CFun thứ, bao gồm cả hello (chức năng).

Vậy ...

Party p; 
p.hello(); 

Không?

2

Điều này có vẻ giống như một trường hợp sử dụng rõ ràng cho kế thừa. Định nghĩa một lớp mới:

#include "CFun.hpp" 

class CFun2 : public CFun 
{ 
    public: 
    void hello() {cout << "hello" << endl;}; 
}; 

Sau đó sử dụng CFun2 thay vì CFun trong mã nguồn của bạn.

4

Bạn có thể xác định lại đẳng cấp như thế này:

#define CFun CLessFun 
#include "CFun.hpp" 
#undef CFun 

class CFun : CLessFun 
{ 
    public: 
    void hello() {cout << "hello" << endl;}; 
}; 

Đặt điều này trong một tập tin tiêu đề mới CMoreFun.hpp và bao gồm việc thay vì CFun.hpp

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