开发者

Classes, Member Functions & Separate compilation

开发者 https://www.devze.com 2023-02-14 21:54 出处:网络
Anyone knows how to implement a function to use Classes and move functionality into the classes. How can i add appropriate member functions (or methods) to each cla开发者_运维问答ss so as to implement

Anyone knows how to implement a function to use Classes and move functionality into the classes. How can i add appropriate member functions (or methods) to each cla开发者_运维问答ss so as to implement the functionality of the function .. maybe possibly adding parametized constructors?? For example, how would i do so for a function initially like this:

//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;
}


findacct is a bad example of a function to be moved inside a class because doesn't do anything on a specific account and just searches among several accounts.

You can move this kind of function inside the BankAccount class as a static member function, but static member functions are really not that different from global functions with fancy names.

Much more interesting for the OOP approach would be moving some function that acts on a specific bank account inside the BankAccount class e.g. something like changing from

bool withdraw(int account_id, int amount)

to

bool BankAccount::withdraw(int amount)

In the following example code I've stored all accounts in a private vector. To create a new account you must call a static class function providing the ID number. Note that this code contains many subtleties and can be dangerous to use as a basis unless you understand it fully... this is unfortunately a characteristic of C++ where apparently logical statements may act logically or can just make your computer to act strangely. My suggestion is to grab a good C++ book and read it cover to cover before or while experimenting with the language.

C++ is just too complex and sometimes illogical (for historical reasons) to learn it just with experimentation.

#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;
}


I'm not sure what you're asking exactly, but here are some observations:

  1. Don't use arrays of constant size. You'll either waste space or overflow them. Use vectors.

  2. Don't use abbreviations like num_accts or acct_num, use readable names. I would replace the former with number_of_accounts and the latter with number, since it is part of a structure.

  3. Don't write linear search algorithms yourself, they are already implemented in the STL. All you have to do is provide a predicate that compares the account numbers.

And here is some example code based on these 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
    }
}

If you have trouble understanding this code, I suggest you get a good C++ book.


The need of writing things like AccountNumberComparer is what makes <algorithm> in my opinion almost useless in C++.

Well, you don't have to write specific code for every find_if call, you can go generic instead:

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));

And of course, Boost already provides a better solution:

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


I'm not sure what programming language you're using, thus I have written brief sudo-code of it, hope it'll help

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;
    }
}

on your main()

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

精彩评论

暂无评论...
验证码 换一张
取 消