class a{
public:
virtual int fun1(int i,int a){return a+1;}
virtual float fun2(int i,int a,float b){return a+b+1;}
virtual double fun3(int i,int a,float b,double c){return a+b+c+1;}
};
class b: public a{
a array1[10];
public:
virtual int fun1(int i,int a){
if(i>=10) return a::fun1(i,a); else return array1[i].fun1(i,a);
}
virtual float fun2(int i,int a,float b){
if(i>=10) return a::fun2(i,a,b); else return array1[i].fun2(i,a,b);
}
virtual double fun3(int i,int a,float b,double c){
if(i>=10) return a::fun3(i,a,b,c); else return array1[i].fun3(i,a,b,c);
}
};
int main(int argc,char* argv[]){
b bb;
cout<<"\n"<<bb.fun3(1,2,3,4);
}
Можно легко заметить, что методы класса b построены по одному алгоритму.
В связи с этим хотелось бы написать шаблон, в который передавать соответствующий метод класса a.
Однако из-за того, что прототипы методов разные, то шаблон написать не получается.
Вопрос:
1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
Здравствуйте, pepsicoca, Вы писали забавный код.
P>Вопрос: P>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
Можно тупо добавить один метод возвращающий ссылку:
class a{
public:
virtual a& get_a(int i) { return *this; }
virtual int fun1(int i,int a){return a+1;}
virtual float fun2(int i,int a,float b){return a+b+1;}
virtual double fun3(int i,int a,float b,double c){return a+b+c+1;}
};
class b: public a{
a array1[10];
public:
virtual a& get_a(int i) { return (i>=10 || i < 0) ? *this : array1[i]; }
}
int main(int argc,char* argv[]){
b bb;
cout<<"\n"<<bb.get_a(1).fun3(1,2,3,4);
}
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, pepsicoca, Вы писали забавный код.
P>>Вопрос: P>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
BFE>Можно тупо добавить один метод возвращающий ссылку:
BFE>
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, pepsicoca, Вы писали забавный код.
P>>Вопрос: P>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
BFE>Можно тупо добавить один метод возвращающий ссылку:
Но все равно спасибо за идею. Не шаблон правда, но все-таки лучше, чем ничего:
<>
(в сторону: странные у тебя подходы к именам — классы a, b и тут же переменные a, b; и к форматированию тоже странный подход: ни одной табуляции)
P>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.
Но возможно, что твои мучения связаны с ошибкой в проектировании.
Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе.
Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, pepsicoca, Вы писали:
К><> К>(в сторону: странные у тебя подходы к именам — классы a, b и тут же переменные a, b; и к форматированию тоже странный подход: ни одной табуляции)
Это последствия тяжелого ассемблерного детства. Но при существующих сейчас средствах форматирования кода это не проблема.
P>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
К>Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.
Не шаблон виртуальной функции (хотя почему бы и нет, шаблоны это же инструмент времени компиляции).
Нужен шаблон, который вызывается внутри методов класса b, и принимает в качестве параметра метод базового класса.
К>Но возможно, что твои мучения связаны с ошибкой в проектировании. К>Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе. К>Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.
Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.
Здравствуйте, pepsicoca, Вы писали:
P>>>Вопрос: P>>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
BFE>>Можно тупо добавить один метод возвращающий ссылку:
P>Но все равно спасибо за идею. Не шаблон правда, но все-таки лучше, чем ничего:
Пожалуйста. Но идея была не в том, чтобы вынести общий код в отдельную функцию, а в том, что вместо класса a всегда использовать proxy-объект (адаптер, если хотите):
class a{
protected:
struct data{
int fun1(int i,int a){return a+1;}
float fun2(int i,int a,float b){return a+b+1;}
double fun3(int i,int a,float b,double c){return a+b+c+1;}
};
data d;
public:
virtual data& get_a(int i) { return d; }
};
class b: public a{
a array1[10];
public:
virtual data& get_a(int i) { return (i>=10 || i < 0) ? d: array1[i].get_a(i); }
};
int main()
{
b bb;
std::cout<<"\n"<<bb.get_a(1).fun3(1,2,3,4);
return 0;
}
Здравствуйте, pepsicoca, Вы писали:
P>Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.
Ну, например, твою задачу можно решить заведя специальный объект "аккумулятор"
тогда у тебя будет виртуальный метод "вернуть аккомулятор для i-й позиции", а у аккумулятора уже будут виртуальные методы add( int ) add( double ) add( char ) и т. д...
Но это если твой пример нам нужен, а не какой-то ещё..
так что лучше понятнее рассказать ЧТО ТЕБЕ НАДО НА САМОМ ДЕЛЕ...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, pepsicoca, Вы писали:
К>>Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.
P>Не шаблон виртуальной функции (хотя почему бы и нет, шаблоны это же инструмент времени компиляции). P>Нужен шаблон, который вызывается внутри методов класса b, и принимает в качестве параметра метод базового класса.
Тут не шаблон, а макрос потребуется. Чтобы нарожать похоже выглядящих методов.
Либо принципиально иное устройство программы.
К>>Но возможно, что твои мучения связаны с ошибкой в проектировании. К>>Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе. К>>Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.
P>Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.
Дьявол в деталях, а ты с подробностями выкинул что-то важное.
И кстати, у тебя наследование хреново решает сразу два паттерна проектирования — нуль-объекты и прокси (а возможно, ещё и флайвейт).
Ответь хотя бы на эти два вопроса: зачем тебе нуль-объекты, и зачем тебе прокси.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, pepsicoca, Вы писали:
К>>>Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.
P>>Не шаблон виртуальной функции (хотя почему бы и нет, шаблоны это же инструмент времени компиляции). P>>Нужен шаблон, который вызывается внутри методов класса b, и принимает в качестве параметра метод базового класса.
К>Тут не шаблон, а макрос потребуется. Чтобы нарожать похоже выглядящих методов. К>Либо принципиально иное устройство программы.
К>>>Но возможно, что твои мучения связаны с ошибкой в проектировании. К>>>Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе. К>>>Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.
P>>Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.
К>Дьявол в деталях, а ты с подробностями выкинул что-то важное. К>И кстати, у тебя наследование хреново решает сразу два паттерна проектирования — нуль-объекты и прокси (а возможно, ещё и флайвейт). К>Ответь хотя бы на эти два вопроса: зачем тебе нуль-объекты, и зачем тебе прокси.
Там нет никаких нуль-объектов.
Класс "a" это таблицы с данными.
Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных.
Методы fun1, fun2, fun3 таскают данные в/из таблиц.
Иногда надо таскать данные из таблиц типа "a", а иногда из таблиц типа "b".
Данные (естественно) таскаются по базе "a".
Примерно так:
На самом деле объекты типа "a" и "b" сами лежат в хранилище и достаются из хранилища по внешним условиям. То есть аргумент функции what_work_now приходит снаружи от пользователя.
Здравствуйте, pepsicoca, Вы писали:
P>Там нет никаких нуль-объектов.
Нуль-объекты у тебя возникали при обращении к элементу массива или дефолтному элементу (самому себе).
Либо можно считать, что у нас просто массив из 11 элементов
P>Класс "a" это таблицы с данными. P>Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных. P>Методы fun1, fun2, fun3 таскают данные в/из таблиц. P>Иногда надо таскать данные из таблиц типа "a", а иногда из таблиц типа "b". P>Данные (естественно) таскаются по базе "a".
Ну не постесняйся, приведи схему твоей базы, а? Чай, не для КГБ программу делаешь, по количеству колонок в таблице мы не узнаем мощность боеголовки или имена резидентов.
P>Класс "a" это таблицы с данными. P>Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных. P>Методы fun1, fun2, fun3 таскают данные в/из таблиц.
Ну, уже на этом этапе открытия тобой подробностей, возникает чувство, что лучше сделать так, что a и b будут просто классами с данными, предоставляющими к данным унифицированный простой и логичный доступ. Возможно, что в b он бует расширеныы.
Соответственно, доступ к этим таблицам можно сделать через шаблонный прокси-объект, который хранит
в себе данное + содержит шаблонный код методов нетривиального доступа.
Ну а если надо ещё и динамичекий полиморфизм сверху навернуть, то просто делаешь оба прокси реализацией одного и того же интерфейса...
Как бы в системе будет три сущности
1) Структуры данных, которые там умеют хранить данные, искать, серализовать и т. д.
2) Прокси для доступа
3) Интерфейс для полиморфизма
И каждая отвечает за свои дела...
P>
Но я уверен. Если ты откроешь больше, тебе посоветуют более в тему
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, pepsicoca, Вы писали:
P>Здравствуйте, B0FEE664, Вы писали:
BFE>>Здравствуйте, pepsicoca, Вы писали забавный код.
P>>>Вопрос: P>>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?
BFE>>Можно тупо добавить один метод возвращающий ссылку:
P>Но все равно спасибо за идею. Не шаблон правда, но все-таки лучше, чем ничего:
P>
Рано я порадовался.
Так нельзя делать.
При вызове:
b bb;
bb->fun1(20,1);
происходит зацикливание вызова fun1, стек проваливается и наступает крах.
Нужно делать так:
virtual int fun1(int i,int a){
int ret;
if(i>=10){
ret=a::fun1(i,a);
}
else{
ret=array1[i].fun1(i,a);
}
return ret;
}
Но, несмотря на похожесть, такие вызовы нельзя завернуть в шаблон, так как прототипы у всех методов разные.
Приходится писать макрос, который не типобезопасен и не трассируется в отладчике.
Это явный недостаток шаблонов.
Дополнительно можно понять, что обращение a::fun1(i,a); вызывает виртуальную функцию fun1 не через таблицу виртуальных функций, а напрямую.
Обращение же по указателю на тип a вызывает виртуальную функцию fun1 через таблицу виртуальных функций.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, pepsicoca, Вы писали:
P>>Там нет никаких нуль-объектов.
К>Нуль-объекты у тебя возникали при обращении к элементу массива или дефолтному элементу (самому себе). К>Либо можно считать, что у нас просто массив из 11 элементов
P>>Класс "a" это таблицы с данными. P>>Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных. P>>Методы fun1, fun2, fun3 таскают данные в/из таблиц. P>>Иногда надо таскать данные из таблиц типа "a", а иногда из таблиц типа "b". P>>Данные (естественно) таскаются по базе "a".
К>Ну не постесняйся, приведи схему твоей базы, а? Чай, не для КГБ программу делаешь, по количеству колонок в таблице мы не узнаем мощность боеголовки или имена резидентов.
Конечно, никакой секретности тут не наблюдается.
На sourceforge.net есть Open Source проект интерпретатора Basic: http://sourceforge.net/projects/obasic/
Я делаю апгрейд этого кода с тем, чтобы поддержать возможность создания локальных в файле меток, переменных и массивов (для уменьшения конфликта имен).
Таблицы a и b это как раз таблицы объектов, которые должны заменяться при переходе от одного файла к другому.
Но весь проект занимает 150 килобайт кода и так мне кажется, что если я запощу на форум 150 килобайт, то модератор меня неправильно поймет.