2008-10-29 17 views
11

Zastanawiam się, czy możliwe jest dodanie metod w programie głównym do istniejącej klasy zdefiniowanej w pliku nagłówkowym. Na przykład: Jest class CFun zdefiniowane w pliku CFun.hpp, ale w naszym party.cpp chcemy dodać metodę void hello() {cout << "hello" << endl;}; bez edytowania CFun.hppC++ dodawanie metody do klasy zdefiniowanej w pliku nagłówkowym

Oczywiście (niestety) budowa:

#include "CFun.hpp" 

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

nie działa Zwracanie błąd Multiple declaration for 'CFun'

Czy można to zrobić bez dziedziczenia klas?

Odpowiedz

9

Nie, ale można dodać metodę, która pobiera odniesienia/wskaźnik do klasy CFun - po prostu nie będzie miał dostępu do danych prywatnych:

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

Jest to prawdopodobnie najlepszy będziesz w stanie zrobić. Jak wskazuje litb - ta funkcja musi znajdować się w tym samym obszarze nazw co CFun. Na szczęście przestrzenie nazw, w przeciwieństwie do klas, można dodawać w wielu miejscach.

+1

należy mu powiedzieć, funkcja musi być w tej samej przestrzeni nazw, takich jak klasa. inaczej po prostu nazywając Hello (some_cfun); nie znajdzie cześć. musiałbyś napisać foo :: Hello (some_cfun); wtedy (ADT nie będzie wtedy działać) –

0

Nie według mojej wiedzy. Chociaż możesz zrobić coś w stylu jury i stworzyć rozwiązanie z przestrzeni nazw.

3

Nie, to niemożliwe. Może istnieć tylko jedna definicja jakiejś konkretnej klasy i musi to być pełna definicja, co oznacza, że ​​nie możesz mieć częściowych definicji w różnych miejscach, dodając członków do klasy.

Jeśli chcesz dodać funkcję członka do klasy, musisz albo zmienić definicję klasy (edytować CFun.hpp), albo wyprowadzić nową klasę z CFun i umieścić tam hello().

0

Po przemyśleniu, możesz zrobić coś strasznego: Znajdź jakąś funkcję w CFun, która ma typ zwrotu, który chcesz, i jest wymieniony tylko raz w całym nagłówku. Powiedzmy: void GoodBye().

Teraz utworzyć CFunWrapper.hpp plik z tej zawartości:

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

Wtedy zawsze tylko to CFunWrapper.hpp zamiast CFun.hpp.

Ale nie rób tego, chyba że jest jakiś dobry powód, aby to zrobić. Jest bardzo podatny na łamanie i może nie być nawet możliwy, zależnie od zawartości CFun.hpp.

+0

Robi to to samo, co modyfikowanie CFun.hpp. Trudno jest pomyśleć o sytuacji, w której to zadziała, ale nie możesz po prostu zmienić pliku nagłówkowego. Myślę, że może to być na ROFS. –

2

Najbliższym analogiem do tego rodzaju konstrukcji (dodanie funkcjonalności do predefiniowanych klas) w C++ jest wzór dekoratora. Nie jest to dokładnie to, czego szukasz, ale może pozwolić ci robić to, czego potrzebujesz.

0
class Party : class CFun 

(Twój party.cpp)

dziedziczy CFun rzeczy, w tym powitania function().

Więc ...

Party p; 
p.hello(); 

Nie?

2

To wydaje się oczywistym przypadkiem użycia dla dziedziczenia. Zdefiniować nową klasę:

#include "CFun.hpp" 

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

Następnie użyj CFun2 zamiast CFun w kodzie źródłowym.

4

Można zmienić klasę tak:

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

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

umieścić to w nowym pliku nagłówkowym CMoreFun.hpp i to, że zamiast CFun.hpp

Powiązane problemy