Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > дружественные классы


Автор: zhenya1 30.9.2010, 19:00
Нужно разбить класс банк на 3 класса. Я уверен, что я это сделал не правильно(т.к. по моему, два дружесвенных дополнительных класса даже не задействованы). Как правильно исправить код?

Код

class person_name;
class person_value;
class bank
{   
private:
    char *bank_name;
    char **name;
    int **value;
    int **salary;
public:
    int n,*vc;
    bank();
    ~bank();
    void setsize();
    void addBank_name();
    void addName();
    void addValue();
    void showBank();
    friend class person_name;
    friend class person_value;
};
class person_name
{
private:
    char **name;
public:
    friend void bank::addName();
};

class person_value
{
private:
int **value;
int **salary;
public:
    friend void bank::addValue();
};
bank::bank()
{
     n=0;
     int **value=0,**salary=0;
     char **name='\0',*bank_name='\0';
}

void bank::setsize()
{
    cout<<" size (n):"<<endl;
    cin>>n;
}

void bank::addBank_name()
{
    bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
    cin>>bank_name;
}

void bank::addName()
{
    char str[55];
    name=new char *[n];

for(int i=0;i<n;i++)
{
    system("cls");
    cout<<i<<":iput name:\n"<<endl;
    cin>>str;
    name[i]=new char[strlen(str)+1];
    strcpy(name[i],str);
}
}
void bank::addValue()
{
    system("cls");
    value=new int *[n];
    salary=new int *[n];
    vc=new int[n];
    for(int i=0;i<n;i++)
    {
        cout<<name[i]<<endl;
    cout<<"input amount of values:";
cin>>vc[i];
value[i]=new int[n];
salary[i]=new int[n];
for(int j=0;j<vc[i];j++)
{
    cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
    }
system("cls");
}
void bank::showBank()
{
    cout<<bank_name<<endl;
    for(int i=0;i<n;i++)
    {
    cout<<name[i]<<"\n";
    for(int j=0;j<vc[i];j++)
    {
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
    }
    }
}
bank::~bank()
{
    delete []bank_name;
    delete []name;
    delete []value;
    delete []salary;
    delete []vc;
}
void main()
{
    bank object;
    object.setsize();
    object.addName();
    object.addValue();
    object.showBank();
    system("pause");
}

Автор: jonie 30.9.2010, 19:03
тут вообще лажа написана. Строка 41-42 это для чего воообще?

Автор: vnf 30.9.2010, 19:09
Исходный код (до переделки) покажите

Автор: zhenya1 30.9.2010, 21:02
вот исходный код. 

Код

class bank
{   
private:
    char *bank_name;
    char **name;
    int **value;
    int **salary;
public:
    int n,*vc;
    bank();
    ~bank();
    void add( );
    void show( );
    void setsize();
    friend void sum(bank ob);
};
bank::bank()
{
     n=0;
     int **value=0,**salary=0;
     char **name='\0',*bank_name='\0';
}
void bank::setsize()
{
    cout<<" size (n):"<<endl;
    cin>>n;
}
void bank::add()
{
    bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
    cin>>bank_name;

    char str[55];
    vc=new int[n];
    name=new char *[n];
    value=new int *[n];
    salary=new int *[n];
for(int i=0;i<n;i++)
{
    system("cls");
    cout<<i<<":iput name:\n"<<endl;
    cin>>str;
    name[i]=new char[strlen(str)+1];
    strcpy(name[i],str);

    cout<<"input amount of values:";
cin>>vc[i];
value[i]=new int[n];
salary[i]=new int[n];
for(int j=0;j<vc[i];j++)
{
    cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
}
system("cls");
}
void bank::show()
{
    cout<<bank_name<<endl;
    for(int i=0;i<n;i++)
    {
    cout<<name[i]<<"\n";
    for(int j=0;j<vc[i];j++)
    {
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
    }
    }
}
void sum(bank ob)
{
    char line[22];int s=0;
    cout<<" input name:"<<endl;
    cin>>line;
    for(int i=0;i<ob.n;i++)
    {
        if(strcmp(line,ob.name[i])==0)
        {
            for(int j=0;j<ob.vc[i];j++)
                s+=ob.salary[i][j];
        }
    }
    cout<<"\n"<<s<<endl;
}

bank::~bank()
{
    delete []name;
    delete []bank_name;
    delete []value;
    delete []salary;
    delete []vc;
}
void main()
{
    bank obj;
    obj.setsize();
    obj.add();
    obj.show();
    sum(obj);
    system("PAUSE");
}

Автор: jonie 30.9.2010, 22:36
zhenya1, ну все-равно в 20-21 строках написана лажа. Что вы в них делаете и ЗАЧЕМ? Я уж не говорю про то, что вы удаляете неверно данные (забываете про удаление "вложенных" массивов)..

Автор: kemiisto 30.9.2010, 22:38
Цитата(zhenya1 @  30.9.2010,  20:00 Найти цитируемый пост)
Я уверен, что я это сделал не правильно

У меня для Вас плохие новости. Не использовать в C++ std::string - это уже неправильно.

Автор: zhenya1 30.9.2010, 23:46
Все, теперь удоляю верно, спасибо что заметили.
Цитата

ну все-равно в 20-21 строках написана лажа. Что вы в них делаете и ЗАЧЕМ?

Я заполнял конструктор по умолчанию, хм..это не обязательно, согласен.
Но проблема в том, что мне нужно разбить мой класс на 3 (предпологаю :один для name , другой для valu  and salary и третий -с ам банк)

Код

class bank
{    
private:
    char *bank_name;
    char **name;
    int **value;
    int **salary;
public:
    int n,*vc;
    bank();
    ~bank();
    void add( );
    void show( );
    void setsize();
};
bank::bank()
{
     n=0;
}
void bank::setsize()
{
    cout<<" size (n):"<<endl;
    cin>>n;
}
void bank::add()
{
    bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
    cin>>bank_name;

    char str[55];
    vc=new int[n];
    name=new char *[n];
    value=new int *[n];
    salary=new int *[n];
for(int i=0;i<n;i++)
{
    system("cls");
    cout<<i<<":iput name:\n"<<endl;
    cin>>str;
    name[i]=new char[strlen(str)+1];
    strcpy(name[i],str);

    cout<<"input amount of values:";
cin>>vc[i];
value[i]=new int[n];
salary[i]=new int[n];
for(int j=0;j<vc[i];j++)
{
    cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
}
system("cls");
}
void bank::show()
{
    cout<<bank_name<<endl;
    for(int i=0;i<n;i++)
    {
    cout<<name[i]<<"\n";
    for(int j=0;j<vc[i];j++)
    {
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
    }
    }
}

bank::~bank()
{
    for(int i=0;i<n;i++)
    {
    delete []name[i];
    delete []value[i];
    delete []salary[i];
    }
    delete []name;
    delete []value;
    delete []salary;
    delete []vc;
    delete []bank_name;
}
void main()
{
    bank obj;
    obj.setsize();
    obj.add();
    obj.show();
    system("PAUSE");
}

Автор: vnf 1.10.2010, 18:33
Код

class Value
{
    int value;
    int salary;
public:
    Value()
    {
        std::cout<<"values:"<<std::endl;
        std::cin>>value;
        std::cout<<"salary:"<<std::endl;
        std::cin>>salary;
    };
    int getSalary()
    {
        return salary;
    };
    void Show()
    {
        std::cout<<value<<" "<<salary<<std::endl;
    };
};

class Client
{
    char name[55];
    int number_values;
              Value * values;
public:
    Client()
    {
                     system("cls");
                     std::cout<<":iput name:\n"<<std::endl;
                     std::cin>>name;
                     std::cout<<"input amount of values:";
           std::cin>>number_values;
                     values = new Value[number_values];
    };
    ~Client()
    {
        delete [] values;
    };
    int getSalary(char * line)
    {
        if(strcmp(line,name))return 0;
        int salary = 0;
        for(int i = 0; i<number_values; i++)
                                salary += values[i].getSalary();
        return salary;
    };
    void Show()
    {
        std::cout<<name<<std::endl;
        for(int i = 0; i<number_values; i++)
            values[i].Show();
    };
};


class Bank
{
    char bank_name[33];
    int number_clients;
    Client * clients;
public:
    Bank():number_clients(0),clients(NULL)
    {
        std::cout<<"input bank_name\n"<<std::endl;
        std::cin>>bank_name;
        std::cout<<" size (n):"<<std::endl;
        std::cin>>number_clients;
        clients = new Client[number_clients];
    };
    ~Bank()
    {
        delete [] clients; 
    };
    void ShowSalary()
    {
        char line[22];
        std::cout<<" input name:"<<std::endl;
        std::cin>>line;
        int salary = 0;
        for(int i = 0; i<number_clients; i++)
                                 salary += clients[i].getSalary(line);
        std::cout<<"\n"<<salary<<std::endl;
    };
    void Show()
    {
        std::cout<<bank_name<<std::endl;
        for(int i = 0; i<number_clients; i++)
            clients[i].Show();
    };
};

void func()
{
    Bank bank;
    bank.Show();
    bank.ShowSalary();

};

вроде как компилиться

Автор: zhenya1 1.10.2010, 19:32
Огромное Вам спасибо, Вы волшебник. Мне с кодом еще дня два разбираться, а то многое не уловил как Вы сделали. Задам пару вопросов:

 1.  Каким образом класс банк общается с другими классами. И почему не нужно предварительно обявлять другие классы и использовать в Bank  friend классы.
  2. Для чего это нужно? :  
 
Код

int getSalary()
    {
        return salary;
    };

3. В классе Client name как стат. массив . В конструкторе вы каждый раз вводим имя, хм .. а где хранятся все именя? Как-то я не понимаю, вводим в массив ,а выводит как в массив строк. Объясните, как это все происходит.

Автор: vnf 1.10.2010, 20:39
1. 
friend объявляют в том случае если объекту одного класса требуется обращаться к закрытым членам объекта другого класса, в реальном коде такое встречается довольно редко. К открытым членам класса может обращаться кто угодно. В нашем случае объект класса банк Bank вызывает открытые члены-функции getSalary(...) и Show() объектов класса Client.

2. 
инкапсуляция, член salary  закрытый, к нему нельзя обратиться из других классов, поэтому создаём открытый метод для получения значения этого члена

3.
внутри объекта Bank храниться указатель на массив его клиентов Client * clients
сам массив создается динамически clients = new Client[number_clients]
каждый элемент массива хранит своё имя в своём члене name


Автор: zhenya1 2.10.2010, 14:29
Спасибо за разьяснения. Но вот еще одна проблемка:
Код

int getSalary(char * line)
    {
        if(strcmp(line,name))return 0;
        int salary = 0;
        for(int i = 0; i<number_values; i++)
                                salary += values[i].getSalary();
        return salary;
    };

Эту ф-цию мне в задании нужно сделать friend, почемуто. Возможно ли это?

Автор: vnf 3.10.2010, 17:04
friend по отношению к классу могут быть или другие классы или просто функции. Вообще по смыслу в этой задаче friend'ами делать нечего, но если надо по условиям задания можно притянуть за уши следующим образом:
Код

class Client
{
...
    friend int getSalary(Client & client, char * line); // объявили функцию дружественной
...
}

int getSalary(Client & client, char * line) // сама функция вне классов
{
    if(strcmp(line,client.name))return 0;
    int salary = 0;
    for(int i = 0; i<client.number_values; i++)
                  salary += client.values[i].getSalary();
    return salary;
}

class Bank
{
...
    void ShowSalary()
    {
        char line[22];
        std::cout<<" input name:"<<std::endl;
        std::cin>>line;
        int salary = 0;
        for(int i = 0; i<number_clients; i++)
                                 salary += getSalary(clients[i], line); // теперь вызываем глобальную функцию а не метод класса
        std::cout<<"\n"<<salary<<std::endl;
    };
...
}




Автор: zhenya1 3.10.2010, 22:15
int getSalary(Client & client, ... -- тут, как я понимаю амперсант это ссылка. Не могли бы Вы пояснить как она работает в данном случае?

Я хочу сделать еще вот что: вводить имя, и если такое имеется , вывести всю информацию о нем. Но с помощью перегрузки оператора"<<".
Код

friend bool operator << (Client obj);
...
bool operator << (Client obj)
{
 char linee[22];
        cout<<" input name:";
        cin>>linee;
 if(strcmp(linee,obj.name)==0)
{
  Client temp[44];
for( i =0 ; ... i++)
temp[i].name=name<< " "<<obj.name;
}
return temp;
}

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)