2008-10-29 2 views
11

Мне интересно, можно ли добавлять методы в основной программе к существующему классу, определенному в файле заголовка. Например: Существует class CFun определено в файле CFun.hpp, но в нашем party.cpp мы хотим добавить метод void hello() {cout << "hello" << endl;}; без редактирования CFun.hppC++ метод добавления к классу, определенному в файле заголовка

Очевидно (к сожалению) строительство:

#include "CFun.hpp" 

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

не работает возвращая error Multiple declaration for 'CFun'

Можно ли заставить его работать без наследования классов?

ответ

9

Нет, но вы можете добавить метод, который принимает ссылку/указатель на класс CFUN - вы просто не будете иметь доступ к частной информации:

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

Это, пожалуй, лучшее, что вы будете способен сделать. Как указано в litb - эта функция должна находиться в том же пространстве имен, что и CFun. К счастью, пространства имен, в отличие от классов, могут быть добавлены в несколько мест.

+1

вы должны сказать ему, что функция должна быть в том же пространстве имен, как класс. иначе просто вызовите Hello (some_cfun); не найдет Hello. вам нужно написать foo :: Hello (some_cfun); тогда (ADT не будет работать тогда) – 2008-11-28 17:27:55

0

Насколько мне известно. Хотя, вы можете сделать какую-то фальсификацию присяжных и создать решение namespace-y.

3

Нет, это невозможно. Может быть только одно определение какого-либо конкретного класса, и оно должно быть полным определением, а это означает, что вы не можете иметь частичные определения в разных местах, добавляя членов в класс.

Если вам нужно добавить функцию-член в класс, то либо вам нужно изменить определение класса (edit CFun.hpp), либо получить новый класс от CFun и поставить там hello().

0

После того, как вы подумали об этом, вы можете сделать что-то страшное: найдите функцию в CFun, у которой есть тип возвращаемого значения, который вы хотите, и упоминается только один раз во всем заголовке. Скажем, void GoodBye().

Теперь создайте файл CFunWrapper.hpp с этим содержимым:

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

Тогда только когда-либо включать CFunWrapper.hpp вместо CFun.hpp.

Но не делайте этого, если только нет веских причин для этого. Он чрезвычайно подвержен взлому и, возможно, даже невозможен, в зависимости от содержимого CFun.hpp.

+0

Выполнение этого же, как только изменение CFun.hpp. Трудно представить себе ситуацию, когда это будет работать, но вы не можете просто изменить заголовочный файл. Думаю, это может быть на ROFS. – 2008-10-29 23:28:36

2

Самый близкий аналог такого типа конструкции (добавление функциональности к предопределенным классам) в C++ - это узор Decorator. Это не совсем то, что вам нужно, но это может позволить вам делать то, что вам нужно.

0
class Party : class CFun 

(ваш party.cpp)

наследует CFUN вещи, в том числе функции приветствия().

Итак ...

Party p; 
p.hello(); 

Нет?

2

Это кажется очевидным прецедентом для наследования. Определите новый класс:

#include "CFun.hpp" 

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

Затем используйте CFun2 вместо CFun в исходном коде.

4

Вы можете переопределить класс вроде этого:

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

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

поместить это в новый файл заголовка CMoreFun.hpp и включают в себя, что вместо CFun.hpp

Смежные вопросы