2011-03-06 2 views
0

Tout le monde sait comment implémenter une fonction pour utiliser des classes et déplacer des fonctionnalités dans les classes. Comment puis-je ajouter des fonctions membres appropriées (ou méthodes) à chaque classe afin de mettre en œuvre la fonctionnalité de la fonction .. peut-être éventuellement ajouter des constructeurs paramétrés ?? Par exemple, comment pourrais-je le faire pour une fonction d'abord comme ceci:Classes, fonctions membres et compilation séparée

//constant definitions 
const int MAX_NUM_ACCOUNTS = 50; 

BankAccount account[MAX_NUM_ACCOUNTS]; 

int findacct(const BankAccount account[], int num_accts, int requested_account); 

{int main()} 

// Function findacct: 
int findacct(const BankAccount account[], int num_accts, int requested_account) 
{ 
    for (int index = 0; index < num_accts; index++) 
     if (account[index].acct_num == requested_account) 
      return index; 
    return -1; 
} 
+0

Félicitations pour avoir compilé '{int main()}' – fizzer

Répondre

0

Je ne suis pas sûr de ce langage de programmation que vous utilisez, ainsi que je l'ai écrit bref code de sudo il, espère que ça aider

Class BankAccount{ 
    //first you need to list its properties e.g. 
    int accountNumber; 
    string name; 

    //and then you can either construct a constructor or just use the default constructor 

    //then you declare your method within the related class 
    int findacc(BankAccount account[], int num_acc, int req_acc){ 
     for(int i=0; i < num_acc; i++){ 
      if... 
       return... 
     } 
     return 1; 
    } 
} 

sur votre principale()

BankAccount bank = new BankAccount(); //calling the constructor 
bank.findacc(pass the parameter) 
+0

Im us dans un langage C++ – NewbieLB

0

findacct est un mauvais exemple d'une fonction à déplacer dans une classe parce que ne fait rien sur un compte spécifique et les recherches seulement parmi plusieurs acco unts.

Vous pouvez déplacer ce type de fonction à l'intérieur de la classe BankAccount en tant que fonction membre static, mais les fonctions membres statiques ne sont vraiment pas différentes des fonctions globales avec des noms de fantaisie.

Beaucoup plus intéressant pour l'approche POO serait de déplacer une fonction qui agit sur un compte bancaire spécifique à l'intérieur de la classe BankAccount, par exemple. quelque chose comme le changement de

bool withdraw(int account_id, int amount) 

à

bool BankAccount::withdraw(int amount) 

Dans le code exemple suivant j'ai stocké tous les comptes dans un vecteur privé. Pour créer un nouveau compte, vous devez appeler une fonction de classe statique fournissant le numéro d'identification. Notez que ce code contient de nombreuses subtilités et peut être dangereux à utiliser à moins que vous ne le compreniez complètement ... ceci est malheureusement une caractéristique de C++ où les instructions apparemment logiques peuvent agir logiquement ou simplement faire fonctionner étrangement votre ordinateur. Ma suggestion est de prendre un bon livre en C++ et de le lire en couverture avant ou pendant l'expérimentation de la langue.

C++ est simplement trop complexe et parfois illogique (pour des raisons historiques) pour l'apprendre juste avec l'expérimentation.

#include <vector> 
#include <algorithm> 
#include <stdlib.h> 
#include <stdio.h> 

class BankAccount 
{ 
private: 
    int id;  // Unique identifier for this account 
    int balance; // How much money is present on this account 

    static std::vector<BankAccount*> accounts; // Global list of valid accounts 

    // Constructor - private! 
    BankAccount(int id) : id(id), balance(0) 
    { 
     // Add to global accounts list 
     accounts.push_back(this); 
    } 

    // Destructor - also private 
    ~BankAccount() 
    { 
     // Remove from global accounts list 
     accounts.erase(std::find(accounts.begin(), accounts.end(), 
           this)); 
    } 

public: 
    // Public global function to create a new account 
    static bool createAccount(int id) 
    { 
     if (find(id) != NULL) 
     { 
      return false; 
     } 
     else 
     { 
      new BankAccount(id); 
      return true; 
     } 
    } 

    // This is a global function that given the unique identifiers 
    // returns a pointer to the account or NULL if non-existent 
    static BankAccount *find(int id) 
    { 
     for (int i=0,n=accounts.size(); i<n; i++) 
      if (accounts[i]->getId() == id) 
       return accounts[i]; 
     return NULL; 
    } 

    // This is a global function that transfers money from one 
    // account to another and returns true if the operation is 
    // successful (i.e. if the source account has enough money) 
    static bool transfer(int from_id, int to_id, int amount) 
    { 
     BankAccount *from = find(from_id); 
     BankAccount *to = find(to_id); 
     if (from != NULL &&   // Is first account valid? 
      to != NULL &&   // Is second account valid? 
      from->withdraw(amount)) // Is there enough money? 
     { 
      to->deposit(amount); // move the withdrawn money 
      return true; 
     } 
     else 
     { 
      // Operation did not succeed 
      return false; 
     } 
    } 

    // Returns the id of the account 
    int getId() 
    { 
     return id; 
    } 

    // Returns the current balance for the account 
    int getBalance() 
    { 
     return balance; 
    } 

    // Deposit a sum on the bank account 
    void deposit(int amount) 
    { 
     balance += amount; 
    } 

    // Tries to withdraw the specified amount from the account 
    bool withdraw(int amount) 
    { 
     if (amount <= balance) 
     { 
      balance -= amount; 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
}; 

// This is also needed; the declaration of accounts inside 
// the class (.h) doesn't actually allocate the vector... simply 
// tells that the following line will be present in a .cpp 
std::vector<BankAccount*> BankAccount::accounts; 

/////////////////////////////////////////////////////////////////////////////////// 

// Do some test... 

#define check(x) \ 
    do { printf("check: %s\n", #x); if (!(x)) {      \ 
      printf("*** Fatal error (line %i)", __LINE__);    \ 
      exit(1); }}while(0) 

int main(int argc, const char *argv[]) 
{ 
    check(BankAccount::createAccount(6502) == true); 
    check(BankAccount::createAccount(386) == true); 

    // duplicate account! 
    check(BankAccount::createAccount(6502) == false); 

    // Not enough founds 
    check(BankAccount::transfer(386, 6502, 1000) == false); 

    // Deposit 
    BankAccount *p386 = BankAccount::find(386); 
    check(p386 != NULL); 
    p386->deposit(1000); 

    // Valid and invalid transfers... 
    check(BankAccount::transfer(386, 6502, 1000) == true); // ok 
    check(BankAccount::transfer(386, 6502, 1000) == false); // No more funds 
    check(BankAccount::transfer(6502, 386, 500) == true); // Give some back 
    check(BankAccount::transfer(386, 6502, 1000) == false); // Not enough funds 
    check(BankAccount::transfer(386, 6502, 400) == true); // ok 
    check(BankAccount::find(386)->getBalance() == 100); 
    check(BankAccount::find(6502)->getBalance() == 900); 
    return 0; 
} 
+0

Ok, je vois ce que vous voulez dire. Pour une fonction comme le retrait .. J'ai une fonction comme ça mais c'est la composition du constructeur qui me déroute. Quant à ce qu'il faut mettre dans les paramètres et dans les {} eux-mêmes. Par exemple ma fonction de retrait: annulation de retrait (compte compte bancaire [], num num_accts, ofstream & out4) – NewbieLB

+0

J'ai ajouté un exemple complet. Notez que vous ne devriez pas l'utiliser à moins que vous ne compreniez complètement chaque partie; apporter des changements qui sembleraient logiquement logiques et compiler même avec des avertissements zéro pourrait encore faire de très mauvaises choses. C'est malheureusement une caractéristique de C++ ... vous devriez d'abord l'apprendre en lisant un bon livre. Apprendre le C++ en expérimentant avec un compilateur est plus ou moins un suicide (C++ est trop complexe et illogique pour cela). – 6502

0

Je ne suis pas sûr de ce que vous demandez exactement, mais voici quelques observations:

  1. Ne pas utiliser des tableaux de taille constante. Vous allez soit gaspiller de l'espace ou les déborder. Utilisez des vecteurs. N'utilisez pas d'abréviations telles que num_accts ou acct_num, utilisez des noms lisibles. Je voudrais remplacer le premier avec number_of_accounts et le dernier avec number, car il fait partie d'une structure. N'écrivez pas d'algorithmes de recherche linéaire vous-même, ils sont déjà implémentés dans la liste STL. Tout ce que vous avez à faire est de fournir un prédicat qui compare les numéros de compte.

Et voici quelques exemples de code à partir de ces observations:

#include <algorithm> 
#include <vector> 

std::vector<BankAccount> accounts; 

class AccountNumberComparer 
{ 
    int account_number; 

public: 

    AccountNumberComparer(int account_number) 
    : account_number(account_number) {} 

    bool operator()(const BankAccount& account) const 
    { 
     return account.number() == account_number; 
    } 
}; 

int main() 
{ 
    // ... 

    std::vector<BankAccount>::iterator it = 
    std::find_if(accounts.begin(), accounts.end(), AccountNumberComparer(123)); 

    if (it != accounts.end()) 
    { 
     // use *it 
    } 
    else 
    { 
     // no such account 
    } 
} 

Si vous avez du mal à comprendre ce code, je vous suggère de faire un good C++ book.


Le besoin d'écrire des choses comme AccountNumberComparer est ce qui fait <algorithm> à mon avis presque inutile en C++.

Eh bien, vous ne ont d'écrire du code spécifique pour chaque appel find_if, vous pouvez aller à la place générique:

template <class Class, typename Result, Result (Class::*MemFun)() const> 
class Comparer 
{ 
    const Result& value; 

public: 

    Comparer(const Result& value) : value(value) {} 

    bool operator()(const Class& x) const 
    { 
     return (x.*MemFun)() == value; 
    } 
}; 

// ... 

std::vector<BankAccount>::iterator it = 
std::find_if(accounts.begin(), accounts.end(), 
      Comparer<BankAccount, int, &BankAccount::number>(123)); 

Et bien sûr, Boost fournit déjà une meilleure solution :

std::vector<BankAccount>::iterator it = 
std::find_if(accounts.begin(), accounts.end(), 
      boost::bind(&BankAccount::number, _1) == 123); 
+1

La nécessité d'écrire des choses comme 'AccountNumberCompare' est ce qui rend' 'à mon avis presque inutile en C++. L'approche déclarative n'est intéressante que lorsque ce que vous obtenez est en réalité plus concis et plus lisible qu'un code explicite. Malheureusement, la syntaxe C++ est trop lourde pour cela (peut-être que C++ 0X lambdas corrigera au moins partiellement ce problème). – 6502

+0

@ 6502 Voir ma mise à jour. – fredoverflow

Questions connexes