c ++ добавление метода к классу, определенному в файле заголовка

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

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

#include "CFun.hpp"

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

не работает возвращает ошибку Multiple declaration for 'CFun'

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


person Moomin    schedule 29.10.2008    source источник


Ответы (8)


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

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

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

person Eclipse    schedule 29.10.2008
comment
вы должны сказать ему, что функция должна находиться в том же пространстве имен, что и класс. в противном случае просто вызов Hello (some_cfun); не найдет Hello. вам нужно будет написать foo :: Hello (some_cfun); тогда (тогда ADT не будет работать) - person Johannes Schaub - litb; 28.11.2008

Вы можете переопределить класс следующим образом:

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

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

Поместите это в новый файл заголовка CMoreFun.hpp и включите его вместо CFun.hpp

person Timo    schedule 21.01.2013

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

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

person Dima    schedule 29.10.2008

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

person Harper Shelby    schedule 29.10.2008

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

#include "CFun.hpp"

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

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

person Tamzin Blake    schedule 15.09.2011

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

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

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

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

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

person Eclipse    schedule 29.10.2008
comment
Это то же самое, что просто изменить CFun.hpp. Довольно сложно придумать ситуацию, в которой это сработает, но вы не можете просто изменить файл заголовка. Я предполагаю, что это могло быть на ROFS. - person Steve Jessop; 30.10.2008

Насколько мне известно, нет. Тем не менее, вы могли бы провести какое-то жюри и создать решение, ориентированное на пространство имен.

person Paul Nathan    schedule 29.10.2008

class Party : class CFun

(ваш party.cpp)

наследует CFun, включая функцию hello ().

So...

Party p;
p.hello();

No?

person Community    schedule 28.11.2008