create an object in switch-case - c++

i use visual studi 2008. (c++)
in my switch case a wanted to create an object, but i doens't work.
is it right, that i can't create an object in a switch case?
if that's right,whats the best way to work around it,
a new method that's creates that object?
edit the code:
switch (causwahl){
case '1':
cAccount *oAccount = new cAccount (ID);
case '2' ....

I can't say for sure with such a vague question, but I'm guessing that you're doing something like this:
switch(foo)
{
case 1:
MyObject bar;
// ...
break;
case 2:
MyObject bar;
// ...
break;
}
This isn't allowed because each case statement has the same scope. You need to provide more scope if you want to use the same variable name:
switch(foo)
{
case 1:
{
MyObject bar;
// ...
break;
}
case 2:
{
MyObject bar;
// ...
break;
}
}

I suggest avoiding switch-case because of this and other problems. You can allow variable definitions by extra curly braces, but that looks messy and causes two levels of indentation. Other problems are that you can only use integer/enum values for cases, that the break statement cannot be used to break from a loop outside the switch. Forgetting to break is also a very common programming mistake that cannot be detected by the compiler (because it is still valid code) and it leads to hard to debug bugs.
Personally I only use switch-case with enum values, and even then never with a default label. This has the benefit of getting me a compile warning (from GCC) if not all possible values of the enum are handled.
There is nothing wrong with if-elses.

switch (choice)
{
case 1:
{
cout<<"\nBike object created********"<<endl;
Bike B1(2,4,50);
V=&B1;
V->Display_Details();
V->CallToll(persons);
break;
}
case 2:
{
cout<<"\n CAR object created********"<<endl;
Car C1(4,8,50);
V=&C1;
V->Display_Details();
V->CallToll(persons);
break;
}
default:
cout<<"You have entered an invalid choice...........Please Enter valid choice........"<<endl;
}

Related

C++ switch empty default case [duplicate]

In the interest of future readers and my own sanity later, I like to make it absolutely clear that switch statements that do not have a default case (due to all cases being covered) or sequential if-elseif-else with a final else that should not do anything must not be omitted and a comment to that effect be included (see example).
However, whenever I include the default case in the switch statement and leave it empty I must put a semicolon inside the default case or a compiler error: " Line [Line of closing brace of switch statement]`missing ';' before '}'" occurs. WHY?!
EXAMPLE: GENERATES COMPILER ERROR
switch(direction) {
case MOVE_UP:
//...
break;
case MOVE_RIGHT:
//...
break;
case MOVE_DOWN:
//...
break;
case MOVE_LEFT:
//...
break;
default:
/* DO NOTHING */
}
EXAMPLE: DOES NOT GENERATE COMPILER ERROR
switch(direction) {
case MOVE_UP:
//...
break;
case MOVE_RIGHT:
//...
break;
case MOVE_DOWN:
//...
break;
case MOVE_LEFT:
//...
break;
default:
/* DO NOTHING */;
}
Because you need a statement for your default case. A semicolon is an empty-statement.
6.1/1 in C++03 gives the grammar for a labeled-statement:
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
C++11 is the same except you can have attributes before the label.
A zero-length sequence of tokens is not a statement in C++, hence default: on its own is not a labeled-statement.
That said, I don't know what the motivation was why the grammar for a labeled-statement doesn't allow default: statementopt. If it did then there would be a grammatical ambiguity if you wrote default : case 1: break;, whether case 1: break; is the statement belonging to default:, or whether default: has no statement of its own, but is immediately followed by one. There's still no doubt what it means, but maybe it was thought that it would mess up people's parsers.

GCC warnings for user types using QVariant::Type in a switch block

Basically we're keeping the track of object types in a variable of QVariant::Type and then doing something like that
switch(values[i].type)
{
case QVariant::Bool: logic; break;
case QVariant::Int: logic; break;
case QVariant::LongLong: logic; break;
case QVariant::String: logic; break;
case QVariant::Double: logic; break;
case QVariant::DateTime:
case QVariant::Date:
case QVariant::Time: logic; break;
case QVariant::User+1:
{
logic;break;
}
case QVariant::User+2:
{
logic;break;
}
default: break;
}
The problem is: gcc produces warnings along these lines for User+X statements:
warning: case value ‘1025’ not in enumerated type ‘QVariant::Type’ [-Wswitch]
Now, I could suppress that of course, but is that the recommended way or am I doing something fundamentally wrong here?
P.S. The question isn't about why the warning is produced: I understand why. The queston is more about using QVariant::Type with user types in a proper way and if simply suppressing is correct or what am I doing here is just plain wrong and warning is an indication of a bigger design decision problem.
If you are going to use user types in the QVariant, you should use the member function userType:
Unfortunately, this will make things uglier:
auto u = [](auto& v){return static_cast<int>(v);};
switch(values[i].userType())
{
case u(QVariant::Bool): logic; break;
case u(QVariant::Int): logic; break;
case u(QVariant::LongLong): logic; break;
case u(QVariant::String): logic; break;
case u(QVariant::Double): logic; break;
case u(QVariant::DateTime):
case u(QVariant::Date):
case u(QVariant::Time): logic; break;
case u(QVariant::User)+1:
{
logic;break;
}
case u(QVariant::User)+2:
{
logic;break;
}
default: break;
}
To clarify: Note that the type() member function will always return QVariant::UserType when the type value is greater than QMetaType::User. This means it will never return QVariant::UserType+n! How could it? Those values are not part of the enumeration.
This is what gcc is warning you about:
warning: case value ‘1025’ not in enumerated type ‘QVariant::Type’ [-Wswitch]
Since 1025(QVariant::User+1) is not part of QVariant::Type, this case label is essentially dead code.
The userType member function, however, returns int. It will return the same underlying value as type when that value is below QMetaType::User, and also the correct user value when above.
From QVariant::type enum:
QMetaType::User 1024 Base value for user types
this is like:
switch(1024) {
...
case (1024 + 1): break;
default: break;
}
the governing rule in switch for enum is to be explicit.
(1024 + 1) is not explicit thus the warning.
UPDATE
As per qvariant.html#type
Returns the storage type of the value stored in the variant. Although
this function is declared as returning QVariant::Type, the return
value should be interpreted as QMetaType::Type. In particular,
QVariant::UserType is returned here only if the value is equal or
greater than QMetaType::User.
Thus, QVariant::UserType + 1 will be dead code.
Time to refactor

C++ cross initiialization error

When compiling the following code it provides me with two errors; "jump to case label" and "crosses initialization of std::ofstream SaveLogin". I am currently using codeblocks with the gnu gcc compiler.
switch(choice) {
case 1:
// login
case 2:
// register
ofstream SaveLogin;
break;
case 3:
// reset password
;}
Thanks for viewing my question-EDIT: my question was flagged as a duplicate of another question but the question specified did not entirely conclude my problem. This post is specifically about my problem although I hope it can hope any other people who are having the same problem
The compiler is correct: C++ does not allow you to skip over a variable declaration in the same scope. goto is similarly restricted.
If you need SaveLogin for all cases then declare it above the switch. If you only need it for case 2 then use scope blocks:
case 2 /*not directly relevant but there's no need for the parentheses*/:
{
// register
ofstream SaveLogin; /*ToDo - more logic here unless it's contained
fully within construction and destruction*/
break;
}
case 3:
Here's a small change to the code that should illustrate the problem:
switch(choice) {
case 1:
// login
case 2:
// register
ofstream SaveLogin;
break;
case 3:
// reset password
SaveLogin << "whatever\n"; // added code
;}
That last line would be legal, because SaveLogin is in scope, but it would get executed only as part of case 3, which skips the initialization of SaveLogin. So the rule is that a jump (switch or goto) can't skip an initializer. One possibility, as #Bathsheba mentions, is to put the definition of SaveLogin above the case statement. Another possibility is to limit the scope of SaveLogin so that the jump doesn't bypass it:
case 2:
{
ofstream SaveLogin;
break;
}
case 3:
With the curly braces, SaveLogin is not in scope at case 3 and the problem has gone away.

Can I use switch-case inside if condition?

I'm making a robot which can avoid an obstacle itself by moving randomly in another direction when it meets an obstacle. Can I use a switch case inside an if condition as a statement, like in the code below?
if(s1)
{
switch(randNumber)
{
case 0:
spincw();
break;
case 1:
spinccw();
break;
case 2:
up();
break;
case 3:
right();
break;
case 4:
back();
break;
}
}
I compiled this but it shows
error: a function-definition is not allowed here before '{' token
Yes you can call switch in if. you can not define a function inside another function. Can you please take a loot at function being defined correctly. Might be the problem is somewhere else. Can you please provide more detail.

Do I need a "Default" statement in this scenario?

Often in school, our lecturers will tell us to always include a Default statement at the end of a switch case statement. However, I have always been wondering is it necessary for ALL (or most) scenario?
Consider the following example in C++:
int num = rand()%3;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
In the case above, I feel that it is impossible to have a case where it can be > 2 or < 0, so do I still need to include a Default statement?
There are similar questions in SO asking for the need of Default in switch-case. The replies given there stated that we should almost at anytime include a Default. But of all the cases I encountered personally, it just seems to be redundant since the Default can never be reached.
Edit: Also, in terms of defensive programming, does this scenario needs a Default statement?
And if I were to add a Default statement. It will only be a error-handling statement, am I right to say that?
Technically, no you don't, because you've covered all possible cases with your switch statement.
However, I always find it useful to include an assertion/exception in the default anyway. Consider the following scenario:
// V1.0.0: Initial version.
int num = rand()%3;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
Later...
// V1.0.0: Initial version.
// V1.0.1: Added a fourth method.
int num = rand()%4;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
In this scenario, developer #2 updated the rand modulus, but didn't actually add the case to handle num == 4. Without the default, you're going to silently fail, and that could cause all kinds of badness that could be very hard to debug. A more maintainable solution might be:
// V1.0.0: Initial version.
// V1.0.1: Added a fourth method.
int num = rand()%4;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
default:
assert(false);
throw InvalidNumException("BUG: Method has not been specified for value of num");
}
When debugging, this would stop the debugger at the assert, and if (god forbid) the missing case makes it all the way to production, you'll get an exception thrown, rather than just running off and doing stuff that shouldn't happen.
EDIT:
I think including a catch-all is a good addition to a defensive programming style. It guarantees that you'll get a useful outcome if you miss a case statement (even if that useful outcome is to cause the program to crash).
EDIT 2:
As Andre Kostur mentioned in a comment to this answer, some compilers will emit warnings if you switch on an enum and forget to handle a case, which is a good reason to not include a default case for an enum switch statement. Refer to Phresnel's answer for more information about that.
its not necessary, but it is a good habit to include it, with a print. I always do something like print "This should NOT happen" in the default (or except) so I know there is something happening which I didnt expect to happen. Computers can sometimes do weird things, be prepared!
Strictly speaking, you do not. However, in larger projects it can help finding or avoiding bugs if you want to change your code later.
For example, imagine you want to add some cases/methods later. If you leave the switch as is, you might have to debug and see why the new method isn't called. On the other hand, throwing a kind of NotImplementedException there will directly lead you to the fact that you forgot to add a case.
Depending on the exact context, it can be a matter of style. What I do sometimes is the following.
Consider that you in some point of time you tweak
int num = rand()%3;
to
int num = rand()%4;
then your switch statement is not correct and complete anymore. For such cases, you could add the following:
default:
throw std::logic_error("Oh noes.");
std::logic_error is for errors by the programming team. Now if your team forgets to update the switch, it will (hopefully early) have an aborting program with a trace to hunt down for.
Downside of default
There is also a downside of including a default-clause. When you switch upon an enum ...
enum class Color {
Red, Green, Blue
};
....
Color c = ....;
switch(c) {
case Color::Red: break;
case Color::Green: break;
};
... some compilers will warn you that not all cases are covered. To shut the compiler up, you can now do two things:
Color c = ....;
switch(c) {
case Color::Red: break;
case Color::Green: break;
default: break;
};
Color c = ....;
switch(c) {
case Color::Red: break;
case Color::Green: break;
case Color::Blue: break;
};
You will realise that of those two alternatives, the latter might be more productive. However, this relies on compiler behaviour. You could still throw an exception in the default, but transform what would be a nice compile time error into a runtime error, of which many agree the former is preferable.
The best of two worlds (portable errors, with the bonus of compile time errors) could be achieved using early exit or structures where you can test afterwards if a case was hit:
Color c = ....;
switch(c) {
case Color::Red: return;
case Color::Green: return;
};
throw std::logic_error(...);
MYSQL mysql = {0};
switch(c) {
case Color::Red: mysql = red_database(); break;
case Color::Green: mysql = green_database(); break;
};
if (!mysql)
throw std::logic_error(...);
do I still need to include a default statement?
You don't need to, as long as the assumption about the possible range of num holds - which it will, as long as you don't change the code that calculates it.
You might want to, to validate that assumption in case it changes in future. That kind of defensive programming can be useful to catch broken assumptions quickly, before they cause major problems.
And if I were to add a Default statement. It will only be a error-handling statement, am I right to say that?
Yes. I'd throw a logic_error, or maybe just terminate the program, to indicate that a logical assumption is invalid.
So let's evolve your code a little bit, to something more realistic:
void processNumber(int maxNum) {
int num = rand()%maxNum;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
}
and here you need to make sure that it is in the set of allowed values [1, 2, 3]. You can check it in number of ways, but you need safeguards and check input carefully and raise errors, even if it is internal function.