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'
Можно ли заставить это работать без наследования классов?
Решение
Нет, но вы можете добавить метод, который получает ссылку / указатель на класс CFun - у вас просто не будет доступа к частным данным:
void Hello(CFun &fun)
{
cout << "hello" << endl;
}
Это, вероятно, лучшее, что вы сможете сделать. Как указывает litb, эта функция должна находиться в том же пространстве имен, что и CFun. К счастью, пространства имен, в отличие от классов, могут быть добавлены в нескольких местах.
Другие советы
Вы можете переопределить класс следующим образом:
#define CFun CLessFun
#include "CFun.hpp"
#undef CFun
class CFun : CLessFun
{
public:
void hello() {cout << "hello" << endl;};
};
Поместите это в новый заголовочный файл CMoreFun.hpp
и включите его вместо CFun.hpp
Нет, это невозможно. У любого конкретного класса может быть только одно определение, и оно должно быть полным определением, означающим, что вы не можете иметь частичные определения в разных местах, добавляя членов в класс.
Если вам нужно добавить функцию-член в класс, то вам нужно либо изменить определение класса (отредактировать CFun.hpp), либо получить новый класс из CFun
и поместить туда hello()
.
Наиболее близким аналогом такого рода конструкции (добавление функциональности к предопределенным классам) в C ++ является шаблон Decorator. Это не совсем то, что вам нужно, но это может позволить вам делать то, что вам нужно.
Это похоже на очевидный вариант использования для наследования. Определите новый класс:
#include "CFun.hpp"
class CFun2 : public CFun
{
public:
void hello() {cout << "hello" << endl;};
};
Затем используйте CFun2
вместо CFun
в своем исходном коде.
Подумав об этом, вы можете сделать что-то ужасное: найти в CFun какую-то функцию с нужным вам типом возврата, который упоминается только один раз во всем заголовке. Допустим, void GoodBye()
.
Теперь создайте файл CFunWrapper.hpp с таким содержанием:
#define GoodBye() Hello() { cout << "hello" << endl; } void GoodBye()
#include "CFun.hpp"
#undef GoodBye
Тогда включайте только CFunWrapper.hpp вместо CFun.hpp.
Но не делайте этого, если только для этого нет веских причин. Он чрезвычайно подвержен взлому и может даже не быть возможным, в зависимости от содержимого CFun.hpp.
Насколько я знаю. Хотя, вы могли бы сделать какую-то фальсификацию присяжных и сделать решение для пространства имен-у.
class Party : class CFun
(ваш party.cpp)
наследует содержимое CFun, включая функцию hello().
Итак...
Party p;
p.hello();
Нет?