Classes, Member Functions & Separate compilation
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:
Don't use arrays of constant size. You'll either waste space or overflow them. Use vectors.
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 withnumber
, since it is part of a structure.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)
精彩评论