Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прегрузка операторов, +,-,=,+=,-=.... 
:(
    Опции темы
initmax
Дата 15.12.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 24.7.2009

Репутация: нет
Всего: нет



Доброго, требуется перегрузить операторы для работы со строками
дабы можно было осуществлять такие записи


Код

//     z = a + b;
//     cout<<z;
//     cout << a += b;
//     cout << a = "asd" + b ;
//     cout << c = a = b;
//     cout << ( c = a ) = b;
//     cout << ( a + b ) = c; // NO Выдать ошибку!
//     cout << "asdf" += z;
//     cout << a[0] << endl;
//     cout << c << endl;


но пока удалось реализовать только это:
Код

mString a = "dfdfdf", b = "sdsdsd", z;
cout<<str1+str2;
cout<<str1-str2;


что подскажите?
Код



#include <stdio.h>
#include <iostream.h>
#include <string.h>

using namespace std;
class mString
{
private:
    char *_str;
public:
    char* getStr(void)const ;
    mString(const char *ch);
    mString(const mString &string);
    mString();
    const mString& operator=(mString &str);
    mString& operator+=(mString &str);
    mString& operator-=(mString &str);
};

//Constructor get OBJ
mString::mString(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l];
    strcpy(_str,string.getStr());
}

//Constructor get String
mString::mString(const char *ch)
{
    int l=strlen(ch);
    _str=new char[l];
    strcpy(_str,ch);
}

//Constructor get NULL parameters
mString::mString(){}

//A new line-length jobs
char* mString::getStr(void)const
{
    int l=strlen(_str);
    char *t=new char[l];
    strcpy(t,_str);
    return t;
}


const mString& mString::operator=(mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l];
    strcpy(_str,string.getStr());
    return *this;
}

mString& mString::operator+=(mString &string){
    this->_str=strcat(this->_str,string.getStr());
    return *this;
}

mString& mString::operator-=(mString &string){
    int l=strlen(string.getStr());
    char *t=new char[l];
    strcpy(t,string.getStr());
    int length=strlen(this->_str);
    if(this->_str[length-1]==32)this->_str[length-1]='\0';
    if(t[0]==32){
        for(int i=0; i<l; i++){
            t[i]=t[i+1];
        }
    }
    this->_str=strcat(this->_str,t);
    return *this;
}

static const mString operator-(mString &strL, mString &strR){
    mString t=strL;
    t-=strR;
    return t;
}
static const mString operator+(mString &strL, mString &strR){
    mString t=strL;
    t+=strR;
    return t;
}


ostream& operator << (ostream& os, const mString& str){
    os<<str.getStr()<<endl;
    return os;

}


int main(void)
{
    mString str1="Super ";
    mString str2="  Puper";
    mString a = "dfdfdf", b = "sdsdsd", z;

    cout<<str1+str2;
    cout<<str1-str2;

     cout<<a;
     cout<<b;

//     z = a + b;
//     cout<<z;
//     cout << a += b;
//     cout << a = "asd" + b ;
//     cout << c = a = b;
//     cout << ( c = a ) = b;
//     cout << ( a + b ) = c; // NO Выдать ошибку!
//     cout << "asdf" += z;
//     cout << a[0] << endl;
//     cout << c << endl;

        return 0;
}


PM MAIL   Вверх
Abyx
Дата 15.12.2009, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



если это С++

#include <stdio.h>
- cstdio

#include <iostream.h>
#include <string.h>
- без .h

и вместо char* _str проще std::string или std::vector<char>
PM MAIL   Вверх
586
Дата 15.12.2009, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 8
Всего: 146



Цитата(initmax @  15.12.2009,  17:18 Найти цитируемый пост)
mString::mString(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l];
    strcpy(_str,string.getStr());
}

Ошибка: выход за пределы массива - Нужно ещё место для символа '\0' в конце строки:
Код
mString::mString(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l+1];
    strcpy(_str,string.getStr());
}

PM   Вверх
xvr
Дата 16.12.2009, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Код

mString& mString::operator+=(mString &string){
    this->_str=strcat(this->_str,string.getStr());
    return *this;
}
Ошибка - выход за пределы _str. Память под _str нужно выделять заново

Код

const mString& mString::operator=(mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l];
    strcpy(_str,string.getStr());
    return *this;
}
Утечка памяти - первоначальное значение _str не удалено

Код

mString::mString(){}
Ошибка - поле _str не проинициализированно. Нужна инициализация пустой строкой (или NULL, но в таком случае необходимо учесть возможность _str быть NULL и во всех остальных методах)

Код

char* mString::getStr(void)const
{
    int l=strlen(_str);
    char *t=new char[l];
    strcpy(t,_str);
    return t;
}
2 ошибки - переполнение буфера (для t), и утечка памяти (для возвращаемого методом значения)
Почему бы не сделать просто
Код

const char* mString::getStr(void)const
{
    return _str;
}
?

Опрератор -= делает вообще что то непонятное  smile 

Это const mString& mString::operator=(mString &string) должно быть таким mString& mString::operator=(const mString &string)

И последнее (добавить в описание класса)
Код

char operator[] (size_t idx) const {return _str[idx];}
char& operator[] (size_t idx) {return _str[idx];}



Это сообщение отредактировал(а) xvr - 16.12.2009, 12:28
PM MAIL   Вверх
initmax
Дата 16.12.2009, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 24.7.2009

Репутация: нет
Всего: нет



Переделал

Код

#include <stdio.h>
#include <iostream.h>
#include <string.h>

using namespace std;
class mString
{
private:
    char *_str;
public:
    char* getStr(void)const ;
    mString(const char *ch);
    mString(const mString &string);
    mString();
    mString& operator=(const mString &str);
    mString& operator+=(const mString &str);
    mString& operator-=(const mString &str);

//    char operator[] (size_t idx) const {return _str[idx];}
//   char& operator[] (size_t idx) {return _str[idx];}
};

//Constructor get OBJ
mString::mString(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l+1];
    strcpy(_str,string.getStr());
}

//Constructor get String
mString::mString(const char *ch)
{
    int l=strlen(ch);
    _str=new char[l+1];
    strcpy(_str,ch);
}

//Constructor get NULL parameters
mString::mString()
{
   _str = NULL;
}

//A new line-length jobs
char* mString::getStr(void)const
{
    return _str;
}



mString& mString::operator=(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l+1];
    strcpy(_str,string.getStr());
    return *this;
}


static const mString operator-( const mString &strL, mString &strR)
{
    mString  t=strL;
    t-=strR;
    return t;
}


ostream& operator << (ostream& os, const mString& str)
{
    os<<str.getStr()<<endl;
    return os;
}


static const mString operator+( mString &strL, mString &strR)
{
    mString t=strL;

    cout<<t;
    t+=strR;
    cout<<t;
    return t;
}



mString& mString::operator+=(const mString &string){

     int l=strlen(string.getStr());
    _str=new char[l+1];
    _str=strcat(_str,string.getStr());
//    return _str;
}

mString& mString::operator-=(const mString &string)
{

}







int main(void)
{
    mString str1="Super";
    mString str2="Max";
    mString str_n;
    mString a = "first", b = "second", z;

    cout<<str1;
     cout<<str2;

     str_n=str2;
     cout<<str_n;

     cout<<str1+str2;


//     z = a + b;
//     cout<<z;
//     a += b;
//     a = "asd" + b ;
//     c = a = b;
//     ( c = a ) = b;
//     ( a + b ) = c; // NO!
//     "asdf" += z;
//     cout << a[0] << endl;
//     cout << c << endl;


    return 0;
}


работает, но на cout<<str1+str2; первое слово выводит крокоязбрами, хотя    cout<<t; в методе

Код

static const mString operator+( mString &strL, mString &strR)
{
    mString t=strL;

    cout<<t;
    t+=strR;
    cout<<t;
    return t;
}



отрабатывает корректно, не отрабатывает конструктор копирования?


допиться таких возможностей
//     a += b;
//     a = "asd" + b ;
//     c = a = b;


можно только благодаря перегрузке функций?

 
PM MAIL   Вверх
xvr
Дата 16.12.2009, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



operator += описан неправильно, должно быть так:
Код

mString& mString::operator+=(const mString &string){
     int l=strlen(string.getStr())+strlen(_str);
    char* nv=new char[l+1];
    strcpy(nv,_str);
    delete[] _str;
    _str=strcat(nv,string.getStr());
    return *this;
}

PM MAIL   Вверх
initmax
Дата 17.12.2009, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 24.7.2009

Репутация: нет
Всего: нет



касательно возможности записать так:

Код

  z="hello"+a;


Организовал перегрузку функций

Код

static const mString operator+( mString &strL, mString &strR)
{
    mString t=strL;
    t+=strR;
    return t;
}


static const mString operator+(char *strL, mString &strR)
{
     int l=strlen(strL);
     mString t;
     t.setStr(strL);
    t+=strR;
    return t;
}


и добаивл езё один метод 
Код

void mString::setStr(char *strL)
{
     int l=strlen(strL);
     _str =new char[l+1];
    strcpy(_str,strL);
}


всё работает, подход верный?
PM MAIL   Вверх
xvr
Дата 17.12.2009, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(initmax @ 17.12.2009,  10:19)
касательно возможности записать так:

Код

  z="hello"+a;


Организовал перегрузку функций

Несколько избыточно. Достаточно сделать оператор const mString operator+(const mString &strL, const mString &strR). Тогда для "aaa"+str компилятор автоматически посторит operator+(mString("aaa"),str)

Цитата

и добаивл езё один метод 
Код

void mString::setStr(char *strL)

Лучше сделать mString& operator=(const char*)

Цитата

всё работает, подход верный?
Подход работоспособный, но идеологически выдержан не до конца  smile 
PM MAIL   Вверх
bsa
Дата 17.12.2009, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



initmax, не забывай, что "xxxx" преобразуется к const char *, а не к char*, так как менять содержимое строкового литерала нельзя.
PM   Вверх
initmax
Дата 17.12.2009, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 24.7.2009

Репутация: нет
Всего: нет



Поборол практически всё:


Код

#include <stdio.h>
#include <iostream.h>
#include <string.h>

using namespace std;
class mString
{
private:
    char *_str;
public:
    char* getStr(void)const ;
    void setStr(char *str);
    mString(const char *ch);
    mString(const mString &string);
    mString();
    ~mString();
    mString& operator=(const mString &str);
    mString& operator+=(const mString &str);
    mString& operator+=(const char *);
    mString& operator-=(const mString &str);

    char operator[] (size_t idx) const {return _str[idx];}
     char& operator[] (size_t idx) {return _str[idx];}
};

//Constructor get NULL parameters
mString::mString()
{
   _str =NULL;
}


mString::~mString()
{
  if(_str)
    delete[] _str;
}



//Constructor get OBJ
mString::mString(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l+1];
    strcpy(_str,string.getStr());
}

//Constructor get String
mString::mString(const char *ch)
{
    int l=strlen(ch);
    _str=new char[l+1];
    strcpy(_str,ch);
}

//A new line-length jobs
char* mString::getStr(void)const
{
    return _str;
}

void mString::setStr(char *str)
{
     int l=strlen(str);
     _str =new char[l+1];
    strcpy(_str,str);
}

mString& mString::operator=(const mString &string)
{
    int l=strlen(string.getStr());
    _str=new char[l+1];
    strcpy(_str,string.getStr());
    return *this;
}


ostream& operator << (ostream& os, const mString& str)
{
    os<<str.getStr()<<endl;
    return os;
}

//Перегружаемые функции +
//################################################################
static const mString operator+( mString &strL, mString &strR)
{
    mString t=strL;
    t+=strR;
    return t;
}


static const mString operator+(char *strL, mString &strR)
{
     int l=strlen(strL);
     mString t;
     t.setStr(strL);
    t+=strR;
    return t;
}

static const mString operator+( mString &strL, char *strR)
{

    mString tmp;
    tmp.setStr(strR);
    strL+=tmp;
    return strL;
}


//Перегружаемые функции -
//################################################################
static const mString operator - (const mString &strL, mString &strR)
{
    mString tmp1;
    mString tmp2;
    int L = strlen(strL.getStr());
    int R = strlen(strR.getStr());

     char* nv1=NULL;
    char* nv2=NULL;

     int i=0;

    for(i=L-1; i>=0; --i)
    {
      if(strL.getStr()[i] != ' ')
      {
          nv1=new char[i];
          strncpy(nv1,strL.getStr(),i+1);
          i=0;
      }
    }

     int k=0,j=0;
    for(j=0; j<R-1; ++j)
    {
      if(strR.getStr()[j] != ' ') {k = j; break;}
    }

    nv2=new char[(j-k)+1];
    for(j=0; j<R; ++j)
    {
       nv2[j]=strR.getStr()[j+k];
    }

    tmp1.setStr(nv1);
    tmp2.setStr(nv2);

//    cout<<"tmp1->>"<<tmp1.getStr();
//    cout<<"tmp2->>"<<tmp2.getStr();

    tmp1+=tmp2;
    return tmp1;
}

//Перегружаемые функции +=, -=
//################################################################
mString& mString::operator+=(const mString &string){
    int l=strlen(string.getStr())+strlen(_str);
    char* nv=new char[l+1];
    strcpy(nv,_str);
    delete[] _str;
    _str=strcat(nv,string.getStr());
    return *this;
}



//Переопределить метод +=?
//для возможности вызова таким образом z="super hello"+=a;
//или же описать ещё одну фцию mString operator+=(const char *str, const mString& s);
mString& mString::operator+=(const char *str){
    int l=strlen((str)+strlen(_str));
    char* nv=new char[l+1];
    strcpy(nv,str);
//    delete[] str;
//    _str=strcat(nv,string.getStr());
    return *this;
}




mString& mString::operator-=(const mString &string)
{
    int l=strlen(string.getStr())+strlen(_str);
    char* nv=new char[l+1];
    strcpy(nv,_str);
    delete[] _str;
    _str=strcat(nv,string.getStr());
    return *this;
}







int main(void)
{
    mString str1="Super Mega   ";
    mString str2="                      Max";
    mString str_n;
    mString a = "first", b = "second", z;

    cout<<"1= "<<str1;
     cout<<"2= "<<str2;


     z=a+b;
     cout<<"3= "<<z;

     z="hello"+a;
     cout<<"4= "<<z;

     z=a+"hello";
     cout<<"5= "<<z;

     z=str1-str2;
     cout<<"6= "<<z;

     z = a+=b;
     cout<<"7= "<<z;


     cout<<"8= "<< a[6] <<"\n";
     cout<<"9= "<< a[1] <<"\n";

     z=a=b;
     cout<<"10= "<<z;

     (z=a)=b;
     cout<<"11= "<<z;

     (z="hello")+=a;
     cout<<"12= "<<z;

     (z="mega hello")-=a;
     cout<<"14= "<<z;


//   z="super hello"+=a;
//   cout<<"15= "<<z;

//   ( z + a ) = b; NO

    return 0;
}


Но ни как не могу осилить следующую форму записи 
 z="super hello"+=a;

тако мыслю:
//1) Переопределить метод +=? для возможности вызова таким образом z="super hello"+=a;
//2) Описать ещё одну фцию mString operator+=(const char *str, const mString& s);

кто может подсказать? спасибо.
PM MAIL   Вверх
bsa
Дата 17.12.2009, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



initmax, такая форма записи недопустима (ты пытаешься изменить rvalue, что недопустимо), именно поэтому бороться с ней не нужно.
PM   Вверх
initmax
Дата 17.12.2009, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 24.7.2009

Репутация: нет
Всего: нет



т.е. Вы хотите сказать что запись плана  z="super hello"+=a; реализовать невозможно вовсе?
PM MAIL   Вверх
bsa
Дата 17.12.2009, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



возможно, только зачем? Эта запись ошибочна, зачем пытаться подставлять под нее костыли?
Попробую объяснить на пальцах.
operator+= возвращает ссылку на объект стоящий слева. В твоем случае - на "super hello"... Но перед этим, этот оператор меняет значение объекта. Таким образом, ты должен добавить к строке "super hello" что-то, затем вернуть ссылку на измененную строку...
Этот оператор можно записать следующим образом:
Код
template<typename T>
Type& operator+=(Type &v, T t);
Теперь рассмотрим частный вариант: Type - это const char[12] (именно к такому типу в первую очередь преобразуется строковый литерал "super hello"), T = const MyString&:
Код
const char(&)[12] operator+=(const char (&v)[12], const MyString &t)
{
   //попробуй написать тут правильную реализацию
}

PM   Вверх
initmax
Дата 17.12.2009, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 24.7.2009

Репутация: нет
Всего: нет



Цитата

возможно, только зачем? Эта запись ошибочна, зачем пытаться подставлять под нее костыли?

Такова лаба, в задании такого не было, но преподаватель решил немного пошутить.
в данном случае const char(&)[12] operator+=(const char (&v)[12], const MyString &t)
смущает статическая размерность массива [12], строка должна подставляться динамической размерности.

исходя из Вашего описания:

Цитата

operator+= возвращает ссылку на объект стоящий слева. В твоем случае - на "super hello"... Но перед этим, этот оператор меняет значение объекта. Таким образом, ты должен добавить к строке "super hello" что-то, затем вернуть ссылку на измененную строку...






реализация должны выглядеть следующим образом:
1) выделить память развмерностью в 2 передаваемых строки
2) скопировать в этот участок памяти строку 1 super hello и строку с объекта 
3) зачистить за собой память
4) вернуть полученую строку или созданный объект кот. содержит новую строку

const char(&)[12] operator+=(const char (&v)[12], const MyString &t)
{
    int l=(strlen(t.getStr())+12);
    char* nv=new char[l+1];
    strcpy(nv,v);
    strcat(nv,t.getStr());
    return *this;
}

ругается на запсиь определения функции - const char(&)[12] operator+=(const char (&v)[12], const MyString &t)

прототип в классе выглядит так 
const char& operator+=(const char &v, const MyString &);


ошибка
main.cpp|66|error: ISO C++ forbids declaration of `MyString' with no type|
станно, ибо на мой взгляд данная функция должна перегружаться.
PM MAIL   Вверх
bsa
Дата 17.12.2009, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



initmax, возможно, причина ошибки в том, что ты не создал класс MyString.

Код
const char(&)[12] operator+=(const char (&v)[12], const MyString &t)
{
    int l=(strlen(t.getStr())+12);
    char* nv=new char[l+1];
    strcpy(nv,v);
    strcat(nv,t.getStr());
    return *this;
}
Ты видимо совсем С++ не знаешь. Откуда ты взял указатель this? Он существует только внутри нестатических методов классов, а в коде выше - просто функция. strlen(t.getStr()) очень оригинальная запись, а метода size() у mString нет? Было бы логично его иметь, чтобы не городить огороды. В любом случае, ты должен вернуть ссылку на v. Но массив v ты не изменил! Более того, так как у тебя есть new[], но нет delete[], возникнет утечка памяти.
Почему я использовал 12? Потому что это длина строки "super hello" + 1 (на символ '\0') равна 12. Ты можешь, конечно, заменить эту страшную конструкцию на const char* для простоты, но тебе это все равно не поможет. Повторяю, в данном контексте использовать оператор сложения с присваиванием просто нельзя.

Ты видимо не понял, запись
Код
mString x;
x += "hello world";
легальна, а вот запись:
Код
"hello world" += x;
Нелегальна. Попробуй скомпилировать: 10 += 5;
Когда ты пишешь: t = "hello" += s, то ты сначала пытаешься сделать "hello" += s, а затем полученный результат присвоить t (не забывай, все операторы присваивания работают справа налево). Но НЕЛЬЗЯ ПРИСВАИВАТЬ КОНСТАНТАМ! Так как "hello" - это константа, которая "вшита" к код программы!
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0776 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.