Форум программистов, компьютерный форум CyberForum.ru

Проверка на корректность операции - C++

Восстановить пароль Регистрация
 
Tochka
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 6
31.07.2012, 20:50     Проверка на корректность операции #1
Добрый день.

Не знаю как лучше задать вопрос.
Смысл идеи таков:
Есть интерфейс типа данных (IVariable) и наследники от него, например: Number, Complex, Matrix.
Необходимо реализовать функцию сложения Sum(IVariable a, IVariable b), так чтобы можно было определить возможность сложения и вернуть значение IVariable суммы чисел.
Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "Math"
 
using namespace std;
 
int main (int argc, char ** args)
{
   Number a (5);
   Complex b (4,2);
   Matrix c (2,2);
   
   cout << a<<"+"<<b<<"="<<sum(a,b)<<endl;
   cout <<b<<"+"<<c<<"="<<sum(b,c)<<endl;
   return 1;
}
Результат:
Bash
1
2
5+4+2i=9+2i
4+2i+{2,2}=нельзя складывать эти типы.
На ум приходит только метод у интерфейса OperationCorrect(int /*Тип операции */, int /* Тип переменной */)
Тогда операцию сложения можно написать так:
C++
1
2
3
4
5
6
7
8
9
const int SUM=1;
IVariable sum(IVariable a, IVariable b)
{
 if(a.OperationCorrect(SUM,b.type)
     return a+b;
 if(b.OperationCorrect(SUM,a.type)
     return b+a;
 return new IErrorSum();
}
Может кто знает более интересней вариант.

P.S. Тип Number ничего не знает про тип Complex и Matrix,
тип Complex и Matrix знают про тип Number.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gooseim
Эксперт C++
500 / 404 / 35
Регистрация: 23.09.2010
Сообщений: 1,139
01.08.2012, 18:35     Проверка на корректность операции #2
Можно, например, сделать метод интерфейса IVariable, который принимает единственный параметр - второй операнд суммы ли других операций.
Этот метод переопределить в разных классах. Каждый класс будет проверять, является ли переданный параметр известным ему типом (тип можно хранить как атрибут или просто проверять на dynamic_cast, первый вариант, все же думаю лучше). Это решение похоже на ваше, но оно позволяет не знать классам того, что можно не знать. Что более логично.
Tochka
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 6
01.08.2012, 18:53  [ТС]     Проверка на корректность операции #3
gooseim, спасибо что подтвердили мою теорию.
А что касается передачи одного параметра, то я наверно не до конца описал задачу, в дальнейшем потребуется переопределить *,/,- и тогда встанет вопрос как разделить, что операция Number*Matrix - является корректной, а Number+Matrix - нет.

Насколько я понимаю это единственный вариант?
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,587
Записей в блоге: 17
01.08.2012, 18:53     Проверка на корректность операции #4
Вариант 1:
C++
1
bool TrySum(IVariable a, IVariable b,IVariable &result);// Возвращает успешность,если успешно результат заносит в result.
Вариант 2:
Реализовать свой класс исключений и ловить их при выполнении операций
C++
1
2
3
4
5
try
  { 
    c=sum(a,b);
  }
catch(myerror &e) { cerr<<e.what()<<endl; }
gooseim
Эксперт C++
500 / 404 / 35
Регистрация: 23.09.2010
Сообщений: 1,139
01.08.2012, 19:17     Проверка на корректность операции #5
Tochka, когда будет другая операция, для нее будет другой виртуальный метод и т.д. Т.е. проверка должна осуществляться в методе операции. Причем в методе производного класса.

Добавлено через 22 минуты
Если делать проверку на валидность в базовом классе, мы нарушим идеологию ООП. Базовый класс не должен ничего знать о своих потомках. И потомки должны знать по минимуму друг о друге.
Tochka
0 / 0 / 0
Регистрация: 31.07.2012
Сообщений: 6
01.08.2012, 19:28  [ТС]     Проверка на корректность операции #6
gooseim, может быть я что-то не понимаю, но я планировал перегрузить операторы вида
"operator Op (IVariable)", а так как, я заведомо не знаю какой тип стоит с лева, а какой с права то предполагал проверку на на знание типа (исходя из неё и переставлять местами элементы).

Avazart, исходя из вашей логики Number+Complex - будет выдавать ошибку, а Complex+Number - будет выдавать правильный вариант?

Добавлено через 2 минуты
Если делать проверку на валидность в базовом классе
В базовом классе будет только чисто виртуальная функция которая будет принимать два параметра, а в потомках необходимо будет её перегружать.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
01.08.2012, 19:28     Проверка на корректность операции #7
Эта тема - прямо-таки классический пример ситуации, для которой придумали double dispatch.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2012, 19:54     Проверка на корректность операции
Еще ссылки по теме:

Проверка на корректность введенных данных C++
C++ Проверка на корректность ввода числа
C++ Проверка указателя на корректность

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
gooseim
Эксперт C++
500 / 404 / 35
Регистрация: 23.09.2010
Сообщений: 1,139
01.08.2012, 19:54     Проверка на корректность операции #8
Цитата Сообщение от Tochka Посмотреть сообщение
const int SUM=1; IVariable sum(IVariable a, IVariable b) { if(a.OperationCorrect(SUM,b.type) return a+b; if(b.OperationCorrect(SUM,a.type) return b+a; return new IErrorSum(); }
Такой вариант не покатит. Объект не являющийся IVariable не сможет вернуть сам себя и себе подобных как IVariable. Можно только IVariable& и const IVariable&. Либо сделать конструктор для IVariable для каждого типа. Это опять нарушение ООП. Принимать IVariable тоже не может.

В общем, походу нет красивого решения, как сделать, чтобы операция a + b возвращала тоже самое, что b + a, если b и a разного типа.
Yandex
Объявления
01.08.2012, 19:54     Проверка на корректность операции
Ответ Создать тему
Опции темы

Текущее время: 15:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru