-1

i am trying to add a developer mode in my program. since duty of car defers every month,i want give my user permission to change every single variables in my program alike duty lccost yen2taka freight

#include <iostream>

using namespace std;

class A
{
public:
    int carbid,duty;

    void Input()
    {
        cout<<"please insert the car price you want to bid for(in yen): ";
        cin>>carbid;

        cout<<"duty of the car: ";
        cin>>duty;
    }

    int Exportcost()
    {
        int exportcost;
        int servicechrg=10;
        int freight=20;
        exportcost=servicechrg+freight+carbid;
        return exportcost;
    }

    int Yen2taka()
    {
        int yen2taka;
        int taka2dollarrate=10;
        int dollar2yen=1;

        yen2taka=((Exportcost())/dollar2yen)*taka2dollarrate;

        return yen2taka;
    }

    int Importcost()
    {
        int importcost;
        int lccost=10;
        int cnfcost=20;

        importcost=lccost+cnfcost;

        return importcost;
    }

    int Totalcosting()
    {
        int total;
        int myprofit=10; //80000

        total=myprofit+Importcost()+Yen2taka();

        cout<<total;

        return total;

    }

    void summary()
    {
        cout<<

    }


};

int main()
{
    x:
    A ob;
    ob.Input();
    ob.Exportcost();
    ob.Yen2taka();
    ob.Importcost();
    ob.Totalcosting();

    int ch;
    cout<<"press 1 to see the summery of the costing or 2 to restart costing again"<<endl;
    cin>>ch;
    switch(ch)
    {
       case 1:
          ob.summary();
          break;
       case 2:
          goto x;
    }
}
bruno
  • 32,421
  • 7
  • 25
  • 37
  • About [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)... – Aconcagua May 04 '19 at 07:44
  • Side note: You should indent all your code by four spaces; this provokes appropriate formatting as such (fixed width font, syntax highlighting, etc). There's a 'code' button for this purpose (`{}`). – Aconcagua May 04 '19 at 07:58

1 Answers1

2

At first, you should collect these parameters in a separate class:

class Configuration // maybe you find a better name...
{
    int m_servicechrg = 10; // default
    int m_freight = 20;
    // ...
public:
    int servicechrg() { return m_servicechrg; }
    void servicechrg(int value); { /* check some limits? */ m_servicechrg = value; }
    int freight() { return m_freight; }
    void freight(int value); { /* check some limits? */ m_freight = value; }
    // ...
};

// will allow you to do:
// C c; std::cout << c;
ostream& operator<<(ostream& s, Configuration const& c)
{
    // which ever formatting is appropriate...
    s << c.servicechrg() << ' ' << c.freight();

    return s;
}

The setters could alternatively return bool to indicate invalid values.

Now you can use this class within main:

Configuration c;
A a;

int cost = a.exportCost(c); // you'd have to adjust signatures...

int value;
switch(ch)
{
case 4:
    if(stc::cin >> freight) // catches invalid user input!
                            // one ALWAYS should do, otherwise you might end up in
                            // your program not working any more
    {
        c.freight(value);
        // or, if you have:
        if(!c.freight(value))
        {
            // some appropriate error message
            // (it's better not to output in the setter, you are more flexible this
            // way – maybe you want different messages at different occasions?)
        }
    }
    else
    {
        // appropriate error handling
    }
    break;
default:
    // handling invalid user input
    // again, you always should; but stream state is not in error state,
    // so you just can print appropriate error message
    break;
}

See this answer for how to correctly handle stream errors.

If you wonder about the differences in error handling: First case is met if user enters non-numerical input, such as ss, second case, if input is numerical, but out of valid range (77).

Now if you don't want to pass the configuration as parameter all the time, you could make a global variable from (but careful, there are some dangers with global variables, use them as sparely as possible) or implement the singleton pattern.

Side notes: goto can be a fine tool sometimes, but it is a dangerous one (and the label's name x isn't a good one, prefer a name that clearly shows intention, such as REENTRY_POINT, LOOP_START, ...). If you can get along without unreasonable effort, prefer such variants:

bool isRunning = true;
do
{
    // ...
    case 2:
        isRunning = false;
        break;
}
while(isRunning);

Sure, an additional variable, an additional check; unfortunately, you cannot use break to exit a (pseudo-) endless loop (for(;;)) (but don't apply this pattern for nested loops, then it gets more and more unreadabla – and ineffcient: bool isExit = false; for(int i = 0; !isExit && i < n; ++i) { for(j = 0; j < n; ++j) { isExit = true; break; } } – see what I mean?). A variant might be:

for(;;)
{
    switch(ch)
    case 1:
        // ...
        //break; <- replace
        continue;
    case 2:
        //
        break;
    } // end of switch
    break; // break the surrounding for(;;) loop
}

But that's not really nice either.

A pretty nice variant allowing to exit the loop in the given case, as there isn't anyhting to do afterwards:

for(;;)
{
    switch(ch)
    {
    case 2:
        // maybe yet some cleaning up here
        return 0;
    default:
        // ...
        break;
    }
}

Drawback: The function's exit point possibly is deeply nested inside the code.

There are yet other tricks to allow this pattern, like packing sub-sections of code in a lambda having a return inside and call that one directly. But that now really starts going beyond the scope...

Finally, if you insist on goto, my variant would rather be:

for(;;)
{
    switch(ch)
    {
    case 2:
        // ...
        goto LOOP_EXIT;
    default:
        // ...
        break;
    }
}
LOOP_EXIT:
return 0; // e. g. main
(void)0;  // if there isn't anything to do in the function any more
          // (labels require an instruction afterwards!)

There won't be a hidden loop now and it is more obvious what you actually are doing. Currently, not really an issue, but if your code grows, the hidden loop gets more and more difficult to spot.

In such cases, I clearly mark the gotos so that another coder can immediately spot the critical code points:

///////////////////////////////////////////////////
// possibly some comment why applying this pattern
goto SOME_LABEL;
///////////////////////////////////////////////////

One could do the same with deeply nested function exit points (return).

Aconcagua
  • 24,880
  • 4
  • 34
  • 59