Recent Changes - Search:

Coding C++

Computing

Object: Protection

Trail Index | Objects 2 | Object Protection

As an example, let's make a bank account.

Step 1

With a global instance of a public object, there is no protection from johnRobber().

/**
 * Objects: bank with struct, unprotected, global
 */


// include standard input/output streams for C++
#include <iostream>
using namespace std; // this is ugly!

/**
 * bank account, fully public (!)
 */

struct SomeBank {
        int account;
        SomeBank():account(0) {}; // constructor
        void deposit(const int v) {
                account += v;
                cout<<"BANK: you have deposited "<<v<<endl;
        }
        int draw(const int v) {
                if (v>account) {
                        cout<<"BANK: request:"<<v<<" balance:"<<account<<endl;
                        cout<<"BANK: Not enough money in your account!\n";
                        return 0;
                }
                account -= v;
                cout<<"BANK: you have drawn "<<v<<endl;
                return v;
        }
};

/*
 * global variable - anybody can get to it without me knowing !
 */

SomeBank myBank;
       
/*
 * Way too easy!
 */

void johnRobber() {
        myBank.account -= 200;
        //cout<<" (quiet robber) \n";
}

int main() {
        myBank.deposit(200);
        int cash1=myBank.draw(50);
        johnRobber(); // if it was called JohnDoe, would you notice it?
        int cash2=myBank.draw(50);
        if (cash2==0) {
                cout<<"My bank has been robbed!\n";
        }
        cout<<"My balance:"<<myBank.account<<" my cash:"<<cash1+cash2<<endl;
}

(:sourcend:)

Step 2

Using a local instance, you already have some more control: johnRobber now needs a handle to the object to be passed to it; but it still can do its job...

/**
 * Objects: bank with struct, unprotected, not global
 */


// include standard input/output streams for C++
#include <iostream>
using namespace std; // this is ugly!

/**
 * bank account, fully public (!)
 */

struct SomeBank {
        int account;
        SomeBank():account(0) {}; // constructor
        void deposit(const int v) {
                account += v;
                cout<<"BANK: you have deposited "<<v<<endl;
        }
        int draw(const int v) {
                if (v>account) {
                        cout<<"BANK: request:"<<v<<" balance:"<<account<<endl;
                        cout<<"BANK: Not enough money in your account!\n";
                        return 0;
                }
                account -= v;
                cout<<"BANK: you have drawn "<<v<<endl;
                return v;
        }
};

/**
 * Now that there is no global, it's not as easy any longer:
 * the robber needs to get hold of it,
 * and with in a peculiar way:
 * argument passing by non-const reference "type&" - will discuss it later.
 */

void johnRobber(SomeBank& aBank) {
        aBank.account -= 200;
        //cout<<" (quiet robber) \n";
}

int main() {
        SomeBank myBank;
        myBank.deposit(200);
        int cash1=myBank.draw(50);
        johnRobber(myBank); // why do I give it my bank ? well, never mind...
        int cash2=myBank.draw(50);
        if (cash2==0) {
                cout<<"My bank has been robbed!\n";
        }
        cout<<"My balance:"<<myBank.account<<" my cash:"<<cash1+cash2<<endl;
}

(:sourcend:)

Step 3

Changing the public struct to a class with private data, johnRobber cannot any longer bypass the access controls; but you still need to be careful of who accesses the object because, even going thorugh the appropriate access methods, the object instance might be used inappropriately.

/**
 * Objects: bank with proper object class
 */


// include standard input/output streams for C++
#include <iostream>
using namespace std; // this is ugly!

/**
 * bank account, protected with "private",
 * limited access by "public" functions
 */

class SomeBank {
private:
        int account;
public:
        SomeBank():account(0) {}; // constructor
        void deposit(const int v) {
                account += v;
                cout<<"BANK: you have deposited "<<v<<endl;
        }
        int draw(const int v) {
                if (v>account) {
                        cout<<"BANK: request:"<<v<<" balance:"<<account<<endl;
                        cout<<"BANK: Not enough money in your account!\n";
                        return 0;
                }
                account -= v;
                cout<<"BANK: you have drawn "<<v<<endl;
                return v;
        }
        int getBalance() const { return account; }
};

/**
 * Sorry John, this does not work...
 */

void johnRobber(SomeBank& aBank) {
        //aBank.account -= 200; //this does not compile anymore
        //cout<<" (quiet robber) \n";
}

/**
 * but Jane can be as dangerous! :-P
 */

void jane(SomeBank& aBank) {
        int howMuch=aBank.getBalance()-20;
        int cash=aBank.draw(howMuch);
        cout<<" ( jane.goesShopping("<<cash<<") )\n";
}

int main() {
        SomeBank myBank;
        myBank.deposit(200);
        int cash1=myBank.draw(50);
        johnRobber(myBank); // why do I give it my bank ? doesn't matter, it's safe!
        jane(myBank); // this is fine, isn't it?
        int cash2=myBank.draw(50);
        if (cash2==0) {
                cout<<"My bank has been robbed! Or not? Jane?!\n";
        }
        // not even I can touch .account directly!
        cout<<"My balance:"<<myBank.getBalance()<<" my cash:"<<cash1+cash2<<endl;
       
        cout<<"PS: if you think this example is sexist, why was a male robber ok with you? ;-)\n";
       
}

(:sourcend:)

Conclusions

"But we are not a bank, we don't care."

Wrong. You get your program wrong, you get your paper wrong, you lose your face. You may blow a nuclear reactor, because your program was wrong...

Using the data protection mechanisms provided by objects you can prevent unwanted modifications by pieces of code external to the object; you can enforce for example admissible ranges for values etc.

(missing: protection of methods)

< Objects 2 | Trail Index | Fully Grown Object >

Edit - History - Print - Recent Changes - Search
Page last modified on February 26, 2009, at 02:37 pm