1 Востаннє редагувалося Betterthanyou (07.12.2015 02:44:49)

Тема: ООП operator і перегрузка функцій операторів, шаблони template, дес...

Вирішив написати невеликий клас (в навчальних цілях, я розумію що він не потрібний) який полегшить роботу з char-ом, в мене виникли такі питання
1) Я хочу щоб мій клас при додаванні рядків повертав char я так і зробив, але якщо додати 3 рядки типу sChar він не працює. Я зробив перегрузку (я не знаю як правильно сказати перегрузка функцій операторів ?) 
char* operator+(sChar ch);
char* operator+(char *ch);
але все одно не робить, no operator "+" matches these operands (80)
2) Я можу зробити так щоб cout виводив sChar ? (без допомоги сторонніх функцій, в мене вже є метод sChToChar)
3) В моєму класі можна десь використати шаблони template ? (я думав в operator, але як)
4) Я в operator+ виділяю динамічно пам'ять мені потрібно її очищувати (delete []) ? (якщо так, то як це зробити ?) моєму класі потрібний деструктор ?

#include <iostream>
#include <conio.h>
#include <string>
using namespace std;

class sChar
{
private:
    char* str;
public:
    sChar(char* ch = "\n") : str(ch) {};//конструктор
    char* operator+(sChar ch);//додати sChar + sChar
    char* operator+(char *ch);//додати sChar + char
    char* sChToChar();//sChar перетворити в char
};

sChar CharTosCh(char *ch)//char перетворити в sChar
{
    return (sChar)ch;
}

char* sChToChar(sChar ch)//sChar перетворити в char
{
    return ch.sChToChar();
}

char* sChar::sChToChar()//sChar перетворити в char
{
    return this->str;
}

char* sChar::operator+(char *ch)//додати sChar + char
{
    int size = strlen(str) + strlen(ch);
    char *cpy = new char[size];
    strcpy(cpy, str);
    strcat(cpy, ch);
    return cpy;
}

char* sChar::operator+(sChar ch)//додати sChar + sChar
{
    int size = strlen(str) + strlen(ch.str);
    char *cpy = new char[size];
    strcpy(cpy, str);
    strcat(cpy, ch.str);
    return cpy;
}

int main()
{
    //створюємо рядок
    sChar g = "string";
    cout << g.sChToChar();

    //додаємо рядки
    sChar var1 = "C", var2 = "++";
    cout << "\n" << var1 + var2;
    
    //додаємо декілька рядків
    cout << CharTosCh((sChar)"\n1" + (sChar)" 2 ") + "3";

    //невдала спроба
    //cout << (sChar)"1" + (sChar)" 2 " + (sChar)"3";

    //як я хочу зробити
    cout << (string)"\n1" + (string)" 2 " + (string)"3";
    
    getch();
    return 0;
}

2 Востаннє редагувалося -=ЮрА=- (07.12.2015 07:29:00)

Re: ООП operator і перегрузка функцій операторів, шаблони template, дес...

Betterthanyou у тебе багато конецптуальних помилок, тому я подаю у виді я к воно потрібно бути, а ти вже запитуватимеш чому так а не інакше

#include <string>
#include <iostream>
using namespace std;
 
class sChar
{
private:
    char* str;
    long  len;
public:
    sChar(const char * ch = 0);
    sChar(const sChar &ch);
    ~sChar();
    sChar& operator+(const sChar &ch);//додати sChar + sChar
    sChar& operator+(const char *ch);//додати sChar + char
    sChar& CharTosCh(const char *ch);
    char * sChToChar() const;//sChar перетворити в char
    long   sChLength() const;
    friend ostream &operator<<(ostream &out, const sChar &ch){
        out<<ch.sChToChar();
        return out;
    }
};

sChar::sChar(const char * ch){
    str = 0;
    len = 0;
    if( ch != 0 )
    {
        len = strlen(ch);
        str = new char[1 + len];
        memcpy(str, ch, len);
        str[len] = 0;
    }
}

sChar::sChar(const sChar &ch){
    str = 0;
    len = 0;
    if( ch.str != 0 )
    {
        len = strlen(ch.str);
        str = new char[1 + len];
        memcpy(str, ch.str, len);
        str[len] = 0;
    }
}

sChar::~sChar(){
    delete str;
}
 
sChar& sChar::CharTosCh(const char *ch)//char перетворити в sChar
{
    delete str;
    len  = 0;
    str  = 0;
    if( ch != 0 )
    {
        len = strlen(ch);
        if( len != 0 )
        {
            str = new char[1 + len];
            memcpy(str, ch, len);
            str[len] = 0;
        }
    }
    return *this;   
}
 
char* sChar::sChToChar() const//sChar перетворити в char
{
    return str;
}

long  sChar::sChLength() const{
    return len;
}
 
sChar& sChar::operator+(const char *ch)//додати sChar + char
{
    char *cpy = 0;
    long size = 0;
    if( ch )
    {
        size  = strlen(ch);
        cpy   = new char[1 + len + size];
        memcpy(cpy, str, len);
        memcpy(cpy + len, ch, size);
        len = len + size;
        cpy[len] = 0;
        delete str;
        str = cpy;
    }
    return *this;
}
 
sChar& sChar::operator+(const sChar &ch)//додати sChar + sChar
{
    return operator+(ch.str);
}
 
int main()
{
    //створюємо рядок
    sChar g = "string";
    cout << g.sChToChar();
 
    //додаємо рядки
    sChar var1 = "C", var2 = "++";
    cout << "\n" << var1 + var2  ;
    
    //додаємо декілька рядків
    cout << (sChar)"\n1" + (sChar)" 2 " + (sChar)"3";
 
    cin.get();
    return 0;
}

http://codepad.org/pVt6BosR

string
C++
1 2 3

Post's attachments

Untitlad.png 42.3 kb, 206 downloads since 2015-12-07 

Подякували: koala, Betterthanyou, leofun013

3 Востаннє редагувалося Betterthanyou (07.12.2015 14:47:08)

Re: ООП operator і перегрузка функцій операторів, шаблони template, дес...

-=ЮрА=- написав:

запитуватимеш чому так а не інакше

1)Навіщо там const-и якщо і без неї клас чудово працює
2)Чому delete str а не delete[] str, квадратні дужки написано використовувати для масивів в книзі C++&Builder я.м. глинський... по якій я вчивсь( і зараз теж єю користуюсь) і тут.
3)Яка логіка в CharTosCh це ж має бути функція
4)Коли зробити присвоєння =

Прихований текст
int main()
{
    //створюємо рядок
    sChar g = "string";
    cout << g.sChToChar() << endl;

    //додаємо рядки
    sChar var1 = "C", var2 = "++";
    var1 = "11";
    cout << "\n" << var1 + var2;

    //додаємо декілька рядків
    cout << (sChar)"\n1" + (sChar)" 2 " + (sChar)"3";

    cin.get();
    return 0;
}

має визваться конструктор так, той логічно що визветься деструктор оскільки попередні дані вже не використовуються і він видаляє str тобто те що зараз там записано, а не перед цім, виникає помилка

4

Re: ООП operator і перегрузка функцій операторів, шаблони template, дес...

1)Навіщо там const-и якщо і без неї клас чудово працює 

- const у програмуванні виконує роль своєрідного запобіжнику, це ключове слово позначає данні які в жодному випадку не повинні бути змінені, це дозволяє ще на етапі компіляції виявити грубі помилки. На швидкоруч ось приклад коли компялітор видє такі помилки http://codepad.org/ixOAz6KZ щоб було зрозуміло навіщо це, трошки модернізуємо приклад, я навмисне зроблю так як роблять багато програмістів http://codepad.org/VubBFtks як видно - код зібрався проте при роботі отримали Segmentation fault, ось тому і слід використовувати конст - це убезпечує

5 Востаннє редагувалося -=ЮрА=- (07.12.2015 18:58:05)

Re: ООП operator і перегрузка функцій операторів, шаблони template, дес...

2)Чому delete str а не delete[] str, квадратні дужки написано використовувати для масивів в книзі C++&Builder я.м. глинський... по якій я вчивсь( і зараз теж єю користуюсь) і тут.

- так все вірно я пропустив [] у delete.

3)Яка логіка в CharTosCh це ж має бути функція

- я не зрозумів питання, це і так функція, дивись ії тіло починаючи з рядка 53

sChar& sChar::CharTosCh(const char *ch)//char перетворити в sChar
{
    delete str;
    len  = 0;
    str  = 0;
    if( ch != 0 )
    {
        len = strlen(ch);
        if( len != 0 )
        {
            str = new char[1 + len];
            memcpy(str, ch, len);
            str[len] = 0;
        }
    }
    return *this;   
}

6

Re: ООП operator і перегрузка функцій операторів, шаблони template, дес...

Стосовно останнього питання, потрібен ще оператор копіювання

#include <string>
#include <iostream>
using namespace std;
 
class sChar
{
private:
    char* str;
    long  len;
public:
    sChar();
    sChar(const char * ch = 0);
    sChar(const sChar &ch);
    ~sChar();
    sChar& operator+(const sChar &ch);//додати sChar + sChar
    sChar& operator+(const char *ch);//додати sChar + char
    sChar& operator=(const char *ch);//присвоїти sChar + char
    sChar& CharTosCh(const char *ch);
    char * sChToChar() const;//sChar перетворити в char
    long   sChLength() const;
    friend ostream &operator<<(ostream &out, const sChar &ch){
        out<<ch.sChToChar();
        return out;
    }
};

sChar::sChar(const char * ch){
    cout<<"DEFAULT CONSTRUCTOR"<<endl;
    str = 0;
    len = 0;
    if( ch != 0 )
    {
        len = strlen(ch);
        str = new char[1 + len];
        memcpy(str, ch, len);
        str[len] = 0;
    }
}
 
sChar::sChar(const sChar &ch){
    cout<<"COPY CONSTRUCTOR"<<endl;
    str = 0;
    len = 0;
    if( ch.str != 0 )
    {
        len = strlen(ch.str);
        str = new char[1 + len];
        memcpy(str, ch.str, len);
        str[len] = 0;
    }
}
 
sChar::~sChar(){
    cout<<"DESTRUCTOR"<<endl;
    delete [] str;
}
 
sChar& sChar::CharTosCh(const char *ch)//char перетворити в sChar
{
    delete str;
    len  = 0;
    str  = 0;
    if( ch != 0 )
    {
        len = strlen(ch);
        if( len != 0 )
        {
            str = new char[1 + len];
            memcpy(str, ch, len);
            str[len] = 0;
        }
    }
    return *this;   
}
 
char* sChar::sChToChar() const//sChar перетворити в char
{
    return str;
}
 
long  sChar::sChLength() const{
    return len;
}
 
sChar& sChar::operator+(const char *ch)//додати sChar + char
{
    cout<<"operator+(const char *ch)"<<endl;
    char *cpy = 0;
    long size = 0;
    if( ch )
    {
        size  = strlen(ch);
        cpy   = new char[1 + len + size];
        memcpy(cpy, str, len);
        memcpy(cpy + len, ch, size);
        len = len + size;
        cpy[len] = 0;
        delete[] str;
        str = cpy;
    }
    return *this;
}
 
sChar& sChar::operator+(const sChar &ch)//додати sChar + sChar
{
    cout<<"operator+(const sChar &ch)"<<endl;
    return operator+(ch.str);
}

sChar& sChar::operator=(const char *ch){
    cout<<"operator=(const char *ch)"<<endl;
    delete str;
    len = 0;
    if( ch )
    {
        len = strlen(ch);
        str = new char[1 + len];
        memcpy(str, ch, len);
        str[len] = 0;
    }
    return *this;
}
 
int main()
{
    //створюємо рядок
    sChar g = "string";
    cout << g.sChToChar() << endl;
 
    //додаємо рядки
    sChar var1 = "C", var2 = "++";
    var1 = "11";
    cout << "\n" << var1 + var2;
 
    //додаємо декілька рядків
    cout << (sChar)"\n1" + (sChar)" 2 " + (sChar)"3";
 
    cin.get();
    return 0;
}

Перевірка http://codepad.org/AGVkmZ5x
Я додав до коду лог, тому можна бачити що де визивається

DEFAULT CONSTRUCTOR
COPY CONSTRUCTOR
DESTRUCTOR
string
DEFAULT CONSTRUCTOR
COPY CONSTRUCTOR
DESTRUCTOR
DEFAULT CONSTRUCTOR
COPY CONSTRUCTOR
DESTRUCTOR
operator=(const char *ch)
operator+(const sChar &ch)
operator+(const char *ch)

11++DEFAULT CONSTRUCTOR
DEFAULT CONSTRUCTOR
DEFAULT CONSTRUCTOR
operator+(const sChar &ch)
operator+(const char *ch)
operator+(const sChar &ch)
operator+(const char *ch)

1 2 3DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR

Подякували: leofun011