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

Перегрузка операторов и абстрактный класс - C++

Восстановить пароль Регистрация
 
Oberyn Martell
5 / 5 / 0
Регистрация: 15.05.2013
Сообщений: 36
07.10.2013, 10:56     Перегрузка операторов и абстрактный класс #1
Имеется два класса (DecString и SymbString), наследуемых от абстрактного AString. Можно ли как-нибудь перегрузить операции - и =, чтобы работа с обоими классами осуществлялась в одном методе Operate класса Action?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class AString {
public:
    virtual ~AString() {};
    virtual const std::string& GetName() const = 0;
    virtual const std::string& GetVal() const = 0;
    virtual const char& GetTip() const = 0;
};
 
class DecString : public AString {
    std::string name;
    std::string val;
    char tip;
public:
    DecString(std::string _name): name(_name), tip('d') {}
    DecString(std::string _name, std::string);
    const std::string& GetName() const { return name; }
    const std::string& GetVal() const { return val; }
    const char& GetTip() const { return tip; }
    void SetVal(std::string _val) { val = _val; }
    int GetSize() const { return sizeof(val); }
    DecString (DecString& pObj);
    DecString& operator= (DecString& pObj);
    DecString operator- (DecString& pObj);
};
 
class SymbString: public AString {
    std::string name;
    std::string val;
    char tip;
public:
    SymbString (std::string _name) : name(_name), tip('s') {}
    SymbString (std::string _name, std::string _val) : name(_name), val(_val), tip('s') {}
    const std::string& GetName() const { return name; }
    const std::string& GetVal() const { return val; }
    const char& GetTip() const { return tip; }
    int GetSize() const { return val.size(); }
    void SetVal(std::string _val) { val = _val; }
    SymbString (SymbString& pObj);
    SymbString& operator= (SymbString& pObj);
    SymbString operator- (SymbString& pObj);
};
 
class Raznost : public Action {
    std::string name;
public:
    Raznost() : name("Разность двух элементов") {}
    void Operate(AString*);
    const std::string& GetName() const { return name; }
};
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
07.10.2013, 11:10     Перегрузка операторов и абстрактный класс #2
Что есть класс Action и метод Operate?
Oberyn Martell
5 / 5 / 0
Регистрация: 15.05.2013
Сообщений: 36
07.10.2013, 11:17  [ТС]     Перегрузка операторов и абстрактный класс #3
Цитата Сообщение от Мимино Посмотреть сообщение
Что есть класс Action и метод Operate?
Прощу прощения, не класса Action, а класса Raznost, который в свою очередь является наследуемым от абстрактного класса Action. Он описывает действия, выполняемые с объектами. Например, класс ShowStr показывает значение строки:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Action {
public:
    virtual ~Action() {}
    virtual void Operate(AString*) = 0;
    virtual const std::string& GetName() const = 0;
};
 
class ShowStr : public Action {
    std::string name;
public:
    ShowStr() : name("Показать символьное значение") {}
    void Operate(AString*);
    const std::string& GetName() const { return name; }
};
 
void ShowStr::Operate(AString* pObj) {
    cout << pObj->GetName() << ": ";
    cout << pObj->GetVal() << endl;
    cin.get();
}
Мимино
 Аватар для Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
07.10.2013, 11:45     Перегрузка операторов и абстрактный класс #4
Для отображения разности перегружать оператор присваивания не обязательно. В чем сложность с перегрузкой оператора "-"? Перегружаете его для каждого класса (у Вас же есть прототипы этих функций) и дальше используете. Вот только метод Operate должен будет либо принимать 2 значения, либо сразу ему отправлять (obj1 - obj2). Или проблема в самой реализации перегрузки оператора?
Oberyn Martell
5 / 5 / 0
Регистрация: 15.05.2013
Сообщений: 36
08.10.2013, 14:34  [ТС]     Перегрузка операторов и абстрактный класс #5
Цитата Сообщение от Мимино Посмотреть сообщение
Для отображения разности перегружать оператор присваивания не обязательно. В чем сложность с перегрузкой оператора "-"? Перегружаете его для каждого класса (у Вас же есть прототипы этих функций) и дальше используете. Вот только метод Operate должен будет либо принимать 2 значения, либо сразу ему отправлять (obj1 - obj2). Или проблема в самой реализации перегрузки оператора?
Собственно, вот перегруженные операторы и метод Operate. Второй объект мы получаем в самом методе с помощью метода SelectObject (выбор объекта из списка).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
SymbString SymbString::operator- (SymbString& pObj) { 
    int pos1 = pObj.GetVal().find(val);
    string _name = "Otvet";
    if (pos1 >= 0) { // если вторая строка содержится как подстрока в первой, удаляем ее из первой
        string _val = pObj.GetVal().substr(0, pos1 - 1) +  pObj.GetVal().substr(pos1 + val.size(), std::string::npos);
        SymbString pObj3(_name);
        pObj3.SetVal(_val);
        return pObj3;
    }
    else // иначе просто возвращаем первую строку
        return pObj;
}
 
DecString DecString::operator- (DecString& pObj) {
    for (int i = 0; i < pObj.GetSize(); ++i)
        if (-1 == alph.find_first_of(pObj.GetVal()[i]))
            return 0;
    long int n1 = atol(pObj.GetVal().c_str());
    long int n2 = atol(val.c_str());
    string _name = "Otvet";
    DecString pObj3(_name);
    long int n3 = n2 - n1;
    stringstream ss;
    ss << n3;
    string _val;
    ss >> _val;
    pObj3.SetVal(_val);
    return pObj3;
}
 
void Raznost::Operate(AString* pObj1) {
    Menu menu1(actionList1);
    AString* pObj2 = menu1.SelectObject(factory);
    AString* pObj3 = pObj1 - pObj2; // на этой строке сообщает, что int нельзя использовать для инициал. AString*
    if ((pObj1 - pObj2) && pObj2)
        cout << pObj1->GetVal() << " - " << pObj2->GetVal() << " = " << pObj3;
    else
        cout << "Невозможно выполнить операцию (несовместимые типы)" << endl;
}
Добавлено через 22 часа 22 минуты
Как реализовать метод Operate, чтобы он производил вычисления как с символьными, там и с десятичными строками?
Oberyn Martell
5 / 5 / 0
Регистрация: 15.05.2013
Сообщений: 36
11.10.2013, 10:52  [ТС]     Перегрузка операторов и абстрактный класс #6
все еще актуально
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
11.10.2013, 14:58     Перегрузка операторов и абстрактный класс #7
Oberyn Martell,
Попробуй создать в самом классе Action виртуальный метод virtual operator-(){};
Если не заработает попробуй явно привести тип pObj1 к pObj2 dynamic_cast<pObj2*>(pObj1)

И вообще я токо от досмотрел ты просто инт присваиваешь
Попробуй эту строчку AString* pObj3 = pObj1 - pObj2; заменить на: AString* pObj3 = &((*pObj1) - (*pObj2)); как то так
Oberyn Martell
5 / 5 / 0
Регистрация: 15.05.2013
Сообщений: 36
11.10.2013, 17:08  [ТС]     Перегрузка операторов и абстрактный класс #8
Уже все сделал. Спасибо за помощь
Веолета
0 / 0 / 0
Регистрация: 29.01.2012
Сообщений: 21
18.10.2013, 15:06     Перегрузка операторов и абстрактный класс #9
Помогите решить задачу.

программу, демонстрирующую работу с объектами двух типов: SymbString(символьная строка) и DecString(десятичная строка), для чего создать систему соответсвующих классов. Каждый объект должен иметь идентификатор(в виде произвольной строки символов)и одно или несколько полей для хранения состояния объекта(один класс является потомков другого).
Клиенту(функции main)должны быть доступны следующие основные операции(методы): создать объект, удалить объект, показать значение объекта, выполнение операции operator +(T s1, T s2), где Т - это либо SymbString, либо DecString. Операции по созданию и удалению объектов инкапсулировать в классе Factory. Предусмотреть меню, позволяющее продемонстрировать заданные операции.
При необходимости в разрабатываемые классы добавляются дополнительные методы(например, конструктор копирования, операция присваивания и т.п)для обеспечения надлежащего функционирования этих классов.

operator +(T s1, T s2)
//для объектов SymbString - конкатенация строк s1 и s2;
//для объектов прочих классов - сложение соответсвующих численных значений с последующим преобразованием к типу Т
Oberyn Martell
5 / 5 / 0
Регистрация: 15.05.2013
Сообщений: 36
18.10.2013, 20:37  [ТС]     Перегрузка операторов и абстрактный класс #10
Цитата Сообщение от Веолета Посмотреть сообщение
Помогите решить задачу.

программу, демонстрирующую работу с объектами двух типов: SymbString(символьная строка) и DecString(десятичная строка), для чего создать систему соответсвующих классов. Каждый объект должен иметь идентификатор(в виде произвольной строки символов)и одно или несколько полей для хранения состояния объекта(один класс является потомков другого).
Клиенту(функции main)должны быть доступны следующие основные операции(методы): создать объект, удалить объект, показать значение объекта, выполнение операции operator +(T s1, T s2), где Т - это либо SymbString, либо DecString. Операции по созданию и удалению объектов инкапсулировать в классе Factory. Предусмотреть меню, позволяющее продемонстрировать заданные операции.
При необходимости в разрабатываемые классы добавляются дополнительные методы(например, конструктор копирования, операция присваивания и т.п)для обеспечения надлежащего функционирования этих классов.

operator +(T s1, T s2)
//для объектов SymbString - конкатенация строк s1 и s2;
//для объектов прочих классов - сложение соответсвующих численных значений с последующим преобразованием к типу Т
SymbString.h :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string>
#include "AString.h"
 
class SymbString: public AString {
    std::string name;
    std::string val;
    char tip;
public:
    SymbString (std::string _name) : name(_name), tip('s') {}
    SymbString (std::string _name, std::string _val) : name(_name), val(_val), tip('s') {}
    const std::string& GetName() const { return name; }
    const std::string& GetVal() const { return val; }
    const char& GetTip() const { return tip; }
    int GetSize() const { return val.size(); }
    void SetVal(std::string _val) { val = _val; }
    SymbString (SymbString& pObj);
    SymbString& operator= (SymbString& pObj);
    SymbString operator+ (SymbString& pObj);
};
SymbString.cpp :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "SymbString.h"
#include <iostream>
#include <string>
 
using namespace std;
 
SymbString::SymbString (SymbString& pObj) {
    name = pObj.name;
    val = pObj.val;
    tip = pObj.tip;
}
 
SymbString& SymbString::operator= (SymbString& pObj) {
    name = pObj.GetName();
    val = pObj.GetVal();
    tip = pObj.GetTip();
    return *this;
}
 
SymbString SymbString::operator+ (SymbString& pObj) {
    string _val = val + pObj.GetVal();
    SymbString pObj3 ("Otvet", _val);
    return pObj3;
}
DecString.h :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#include "AString.h"
 
const std::string alph = "0123456789";
bool IsDecStrVal(std::string);
 
class DecString : public AString {
    std::string name;
    std::string val;
    char tip;
public:
    DecString(std::string _name): name(_name), tip('d') {}
    DecString(std::string _name, std::string);
    const std::string& GetName() const { return name; }
    const std::string& GetVal() const { return val; }
    const char& GetTip() const { return tip; }
    void SetVal(std::string _val) { val = _val; }
    int GetSize() const { return sizeof(val); }
    DecString (DecString& pObj);
    DecString& operator= (DecString& pObj);
    DecString operator+ (DecString& pObj);
};
DecString.cpp :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "DecString.h"
#include <iostream>
#include <string>
#include <sstream>
 
using namespace std;
 
bool IsDecStrVal(string _str) {
    for (int i = 0; i < _str.size(); ++i)
        if (-1 == alph.find_first_of(_str[i]))
            return false;
    return true;
}
 
DecString::DecString(string _name, string _val) :
    name(_name), tip('d') {
        if (IsDecStrVal(_val))
            val = _val;
}
 
DecString::DecString (DecString& pObj) {
    name = pObj.name;
    val = pObj.val;
    tip = pObj.tip;
}
 
DecString& DecString::operator= (DecString& pObj) {
    name = pObj.GetName();
    val = pObj.GetVal();
    tip = pObj.GetTip();
    return *this;
}
 
DecString DecString::operator+ (DecString& pObj) {
    long int n1 = atol(pObj.GetVal().c_str());
    long int n2 = atol(val.c_str());
    string _name = "Otvet";
    DecString pObj3(_name);
    long int n3 = n2 + n1;
    stringstream ss;
    ss << n3;
    string _val;
    ss >> _val;
    pObj3.SetVal(_val);
    return pObj3;
}
Summa.h :
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "Action.h"
#include <string>
 
class Summa : public Action {
    std::string name;
public:
    Summa() : name("Сумма двух элементов") {}
    void Operate(AString*);
    const std::string& GetName() const { return name; }
};
 
extern Summa summa;
Summa.cpp :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "Summa.h"
#include "Factory.h"
#include "Menu.h"
#include "ShowOct.h"
#include "ShowStr.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include "SymbString.h"
#include "OctString.h"
 
using namespace std;
 
Action* pActs1[] = { &summa };
vector<Action*> actionList1(pActs1, pActs1 + sizeof(pActs1)/sizeof(Action*));
 
void Summa::Operate(AString* pObj1) {
    Menu menu1(actionList1);
    AString* pObj2 = menu1.SelectObject(factory);
    if (dynamic_cast<DecString*>(pObj2) && dynamic_cast<DecString*>(pObj1)) {
        DecString _pObj2 (pObj2->GetName(), pObj2->GetVal());
        DecString _pObj1 (pObj1->GetName(), pObj1->GetVal());
        DecString pObj3 = _pObj1 + _pObj2;
        cout << pObj1->GetVal() << " + " << pObj2->GetVal() << " = " << pObj3.GetVal() << endl;
        return;
    }
    if (dynamic_cast<SymbString*>(pObj2) && dynamic_cast<SymbString*>(pObj1)) {
        SymbString _pObj2 (pObj2->GetName(), pObj2->GetVal());
        SymbString _pObj1 (pObj1->GetName(), pObj1->GetVal());
        SymbString pObj3 = _pObj1 + _pObj2;
        cout << pObj1->GetVal() << " + " << pObj2->GetVal() << " = " << pObj3.GetVal() << endl;
        return;
    }
    else
        cout << "Невозможно выполнить операцию (несовместимые типы)" << endl;
}
 
Summa summa;
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4923 / 2666 / 243
Регистрация: 29.11.2010
Сообщений: 7,421
19.10.2013, 03:32     Перегрузка операторов и абстрактный класс #11
Небольшие замечания:
Проверяйте в операторе присваиваний присвоение самому себе,
Имена, начинающиеся с нижнего подчеркивания зарезервированы для разработчиков компиляторов, их лучше не использовать.
Глобальные переменные лучше избегать в любом их виде.
std::string name логичнее было бы засунуть в Action т.к. действие обладает именем. Вдобавок, оно имеет метод GetName, а никакого другого типа, кроме как std::string для name не прогнозируется и смысловая нагрузка у данного свойства всех наследников одинаковая.
имена функций принято писать с маленькой буквы, в отличии от имен класса.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.10.2013, 14:22     Перегрузка операторов и абстрактный класс
Еще ссылки по теме:

Перегрузка операторов, если класс содержит массив C++
C++ Перегрузка операторов сравнения и разницы. Класс String
C++ Перегрузка операторов. Класс String

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

Или воспользуйтесь поиском по форуму:
Веолета
0 / 0 / 0
Регистрация: 29.01.2012
Сообщений: 21
19.10.2013, 14:22     Перегрузка операторов и абстрактный класс #12
Oberyn Martell, Спасибо Вам Большое!!!!
Yandex
Объявления
19.10.2013, 14:22     Перегрузка операторов и абстрактный класс
Ответ Создать тему
Опции темы

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