类、成员函数和单独编译

发布于 2024-10-20 15:59:30 字数 583 浏览 1 评论 0原文

任何人都知道如何实现一个函数来使用类并将功能移动到类中。我如何向每个类添加适当的成员函数(或方法)以实现该函数的功能..也许可能添加参数化构造函数?例如,对于最初这样的函数,我将如何执行此操作:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风苍溪 2024-10-27 15:59:30

findacct 是一个在类中移动函数的糟糕示例,因为它不会对特定帐户执行任何操作,而只是在多个帐户之间进行搜索。

您可以将此类函数作为static 成员函数移至 BankAccount 类中,但静态成员函数实际上与具有奇特名称的全局函数没有什么不同。

对于 OOP 方法来说,更有趣的是在 BankAccount 类中移动一些作用于特定银行帐户的函数,例如从 更改为

bool withdraw(int account_id, int amount)

bool BankAccount::withdraw(int amount)

下面的示例代码中,我将所有帐户存储在私有中向量。要创建新帐户,您必须调用提供 ID 号的静态类函数。请注意,这段代码包含许多微妙之处,除非您完全理解它,否则用作基础可能会很危险...不幸的是,这是 C++ 的一个特征,其中明显的逻辑语句可能会按逻辑运行,或者可能会让您的计算机表现得很奇怪。我的建议是在尝试该语言之前或同时,阅读一本好的 C++ 书籍并从头到尾地阅读它。

C++ 太复杂,有时不合逻辑(由于历史原因),无法仅通过实验来学习它。

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

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;
}
临走之时 2024-10-27 15:59:30

我不确定您到底在问什么,但这里有一些观察结果:

  1. 不要使用恒定大小的数组。你要么浪费空间,要么溢出它们。使用向量。

  2. 不要使用缩写,如 num_accts 或 acct_num,使用可读的名称。我会将前者替换为 number_of_accounts,将后者替换为 number,因为它是结构的一部分。

  3. 不要自己编写线性搜索算法,它们已经在 STL 中实现了。您所要做的就是提供一个比较帐号的谓词。

下面是一些基于这些观察结果的示例代码:

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

如果您在理解这段代码时遇到困难,我建议您阅读一本优秀的 C++ 书籍


在我看来,编写像 AccountNumberComparer 这样的东西的需要使得 在 C++ 中几乎毫无用处。

好吧,您不必为每个 find_if 调用编写特定的代码,您可以使用通用代码:

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

当然,Boost 已经提供了更好的解决方案:

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

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);
柠栀 2024-10-27 15:59:30

我不确定你使用的是什么编程语言,因此我编写了简短的 sudo 代码,希望它对

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

你的 main()有帮助

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

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文