доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 12.02.13 12:03
Оценка:
Добрый день.

Есть MSVC2010 и есть код:


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?

Спасибо
Re: доступ к полям с помощью шаблона-2
От: B0FEE664  
Дата: 12.02.13 12:20
Оценка:
Здравствуйте, 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);

}
И каждый день — без права на ошибку...
Re[2]: доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 12.02.13 12:32
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, pepsicoca, Вы писали забавный код.


P>>Вопрос:

P>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?

BFE>Можно тупо добавить один метод возвращающий ссылку:


BFE>
BFE>class a{
BFE>public:
BFE>virtual a& get_a(int i) { return *this; }
BFE>virtual int fun1(int i,int a){return a+1;}
BFE>virtual float fun2(int i,int a,float b){return a+b+1;}
BFE>virtual double fun3(int i,int a,float b,double c){return a+b+c+1;}

BFE>};

BFE>class b: public a{

BFE>a array1[10];
BFE>public:
BFE>  virtual a& get_a(int i) { return (i>=10 || i < 0) ? *this : array1[i]; }
BFE>}

BFE>int main(int argc,char* argv[]){

BFE>b bb;

BFE>cout<<"\n"<<bb.get_a(1).fun3(1,2,3,4);

BFE>}
BFE>


Нет, для класса b нужны такие же методы fun1, fun2, fun3 как и для класса a.
Потому, что иногда методы класса b вызывается по указателю на класс a.
Re[2]: доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 12.02.13 13:07
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, pepsicoca, Вы писали забавный код.


P>>Вопрос:

P>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?

BFE>Можно тупо добавить один метод возвращающий ссылку:


Но все равно спасибо за идею. Не шаблон правда, но все-таки лучше, чем ничего:


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];

a* getptr(int i){
if(i>=10) return (a*)this; else return &(array1[i]);
}

public:

virtual int fun1(int i,int a){return this->getptr(i)->fun1(i,a);}
virtual float fun2(int i,int a,float b){return this->getptr(i)->fun2(i,a,b);}
virtual double fun3(int i,int a,float b,double c){return this->getptr(i)->fun3(i,a,b,c);}
};
Re: доступ к полям с помощью шаблона-2
От: Кодт Россия  
Дата: 12.02.13 13:32
Оценка:
Здравствуйте, pepsicoca, Вы писали:

<>
(в сторону: странные у тебя подходы к именам — классы a, b и тут же переменные a, b; и к форматированию тоже странный подход: ни одной табуляции)

P>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?


Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.

Но возможно, что твои мучения связаны с ошибкой в проектировании.
Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе.
Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.
Перекуём баги на фичи!
Re[2]: доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 12.02.13 13:44
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, pepsicoca, Вы писали:


К><>

К>(в сторону: странные у тебя подходы к именам — классы a, b и тут же переменные a, b; и к форматированию тоже странный подход: ни одной табуляции)

Это последствия тяжелого ассемблерного детства. Но при существующих сейчас средствах форматирования кода это не проблема.

P>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?


К>Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.


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

К>Но возможно, что твои мучения связаны с ошибкой в проектировании.

К>Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе.
К>Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.

Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.
Re[3]: доступ к полям с помощью шаблона-2
От: B0FEE664  
Дата: 12.02.13 14:59
Оценка:
Здравствуйте, 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;
}
И каждый день — без права на ошибку...
Re[3]: доступ к полям с помощью шаблона-2
От: Erop Россия  
Дата: 12.02.13 15:09
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.


Ну, например, твою задачу можно решить заведя специальный объект "аккумулятор"
тогда у тебя будет виртуальный метод "вернуть аккомулятор для i-й позиции", а у аккумулятора уже будут виртуальные методы add( int ) add( double ) add( char ) и т. д...

Но это если твой пример нам нужен, а не какой-то ещё..

так что лучше понятнее рассказать ЧТО ТЕБЕ НАДО НА САМОМ ДЕЛЕ...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: доступ к полям с помощью шаблона-2
От: Кодт Россия  
Дата: 12.02.13 15:35
Оценка:
Здравствуйте, pepsicoca, Вы писали:

К>>Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.


P>Не шаблон виртуальной функции (хотя почему бы и нет, шаблоны это же инструмент времени компиляции).

P>Нужен шаблон, который вызывается внутри методов класса b, и принимает в качестве параметра метод базового класса.

Тут не шаблон, а макрос потребуется. Чтобы нарожать похоже выглядящих методов.
Либо принципиально иное устройство программы.

К>>Но возможно, что твои мучения связаны с ошибкой в проектировании.

К>>Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе.
К>>Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.

P>Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.


Дьявол в деталях, а ты с подробностями выкинул что-то важное.
И кстати, у тебя наследование хреново решает сразу два паттерна проектирования — нуль-объекты и прокси (а возможно, ещё и флайвейт).
Ответь хотя бы на эти два вопроса: зачем тебе нуль-объекты, и зачем тебе прокси.
Перекуём баги на фичи!
Re[4]: доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 12.02.13 16:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, pepsicoca, Вы писали:


К>>>Шаблон виртуальной функции — это фантастика. Или шаблон, или виртуальная.


P>>Не шаблон виртуальной функции (хотя почему бы и нет, шаблоны это же инструмент времени компиляции).

P>>Нужен шаблон, который вызывается внутри методов класса b, и принимает в качестве параметра метод базового класса.

К>Тут не шаблон, а макрос потребуется. Чтобы нарожать похоже выглядящих методов.

К>Либо принципиально иное устройство программы.

К>>>Но возможно, что твои мучения связаны с ошибкой в проектировании.

К>>>Может, тебе не наследование нужно, на самом деле, а... ну есть же разные способы и для полиморфизма в том числе.
К>>>Хотелось бы увидеть более реальную задачу, а не пересушенный-перешифрованный код "классы a, b и функции fun1..fun3 занимающиеся ерундой". Как эти объекты создаются, как используются.

P>>Там слишком много. Я привел упрощенный вариант, чтобы не забивать проблему ненужными подробностями.


К>Дьявол в деталях, а ты с подробностями выкинул что-то важное.

К>И кстати, у тебя наследование хреново решает сразу два паттерна проектирования — нуль-объекты и прокси (а возможно, ещё и флайвейт).
К>Ответь хотя бы на эти два вопроса: зачем тебе нуль-объекты, и зачем тебе прокси.

Там нет никаких нуль-объектов.

Класс "a" это таблицы с данными.
Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных.
Методы fun1, fun2, fun3 таскают данные в/из таблиц.
Иногда надо таскать данные из таблиц типа "a", а иногда из таблиц типа "b".
Данные (естественно) таскаются по базе "a".
Примерно так:


a aa;
b bb;

a* what_work_now(bool flag)(if(flag==true) return &aa; else return &bb;)

main(){

a* ptr;

ptr=what_work_now(true);

ptr->fun1(...);
ptr->fun2(...);
ptr->fun3(...);

ptr=what_work_now(false);

ptr->fun1(...);
ptr->fun2(...);
ptr->fun3(...);

}


На самом деле объекты типа "a" и "b" сами лежат в хранилище и достаются из хранилища по внешним условиям. То есть аргумент функции what_work_now приходит снаружи от пользователя.
Re[5]: доступ к полям с помощью шаблона-2
От: Кодт Россия  
Дата: 12.02.13 18:03
Оценка: +1
Здравствуйте, pepsicoca, Вы писали:

P>Там нет никаких нуль-объектов.


Нуль-объекты у тебя возникали при обращении к элементу массива или дефолтному элементу (самому себе).
Либо можно считать, что у нас просто массив из 11 элементов

P>Класс "a" это таблицы с данными.

P>Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных.
P>Методы fun1, fun2, fun3 таскают данные в/из таблиц.
P>Иногда надо таскать данные из таблиц типа "a", а иногда из таблиц типа "b".
P>Данные (естественно) таскаются по базе "a".

Ну не постесняйся, приведи схему твоей базы, а? Чай, не для КГБ программу делаешь, по количеству колонок в таблице мы не узнаем мощность боеголовки или имена резидентов.
Перекуём баги на фичи!
Re[5]: доступ к полям с помощью шаблона-2
От: Erop Россия  
Дата: 12.02.13 19:20
Оценка: +1
Здравствуйте, pepsicoca, Вы писали:


P>Класс "a" это таблицы с данными.

P>Класс "b" это такие же таблицы с данными, но немного расширенные для другого случая хранения данных.
P>Методы fun1, fun2, fun3 таскают данные в/из таблиц.

Ну, уже на этом этапе открытия тобой подробностей, возникает чувство, что лучше сделать так, что a и b будут просто классами с данными, предоставляющими к данным унифицированный простой и логичный доступ. Возможно, что в b он бует расширеныы.

Соответственно, доступ к этим таблицам можно сделать через шаблонный прокси-объект, который хранит
в себе данное + содержит шаблонный код методов нетривиального доступа.

Ну а если надо ещё и динамичекий полиморфизм сверху навернуть, то просто делаешь оба прокси реализацией одного и того же интерфейса...

Как бы в системе будет три сущности
1) Структуры данных, которые там умеют хранить данные, искать, серализовать и т. д.
2) Прокси для доступа
3) Интерфейс для полиморфизма
И каждая отвечает за свои дела...

P>

Proxy<a> aa;
Proxy<b> bb;

IProxy* what_work_now(bool flag)(if(flag==true) return &aa; else return &bb;)

main()
{

    IProxy* ptr;

    ptr=what_work_now(true);

    ptr->fun1(...);
    ptr->fun2(...);
    ptr->fun3(...);

    ptr=what_work_now(false);

    ptr->fun1(...);
    ptr->fun2(...);
    ptr->fun3(...);

}


Но я уверен. Если ты откроешь больше, тебе посоветуют более в тему
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 14.02.13 08:29
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>Здравствуйте, B0FEE664, Вы писали:


BFE>>Здравствуйте, pepsicoca, Вы писали забавный код.


P>>>Вопрос:

P>>>1. Можно ли такую задачу решить шаблоном или придется тупо руками писать все методы класса b?

BFE>>Можно тупо добавить один метод возвращающий ссылку:


P>Но все равно спасибо за идею. Не шаблон правда, но все-таки лучше, чем ничего:


P>

P>class a{
P>public:

P>virtual int fun1(int i,int a){return a+1;}
P>virtual float fun2(int i,int a,float b){return a+b+1;}
P>virtual double fun3(int i,int a,float b,double c){return a+b+c+1;}

P>};

P>class b: public a{

P>a array1[10];

P>a* getptr(int i){
P>if(i>=10) return (a*)this; else return &(array1[i]);
P>}

P>public:

P>virtual int fun1(int i,int a){return this->getptr(i)->fun1(i,a);}
P>virtual float fun2(int i,int a,float b){return this->getptr(i)->fun2(i,a,b);}
P>virtual double fun3(int i,int a,float b,double c){return this->getptr(i)->fun3(i,a,b,c);}
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 через таблицу виртуальных функций.
Re[6]: доступ к полям с помощью шаблона-2
От: pepsicoca  
Дата: 14.02.13 08:39
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 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 килобайт, то модератор меня неправильно поймет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.