c++| Chinese traps six. Virtual methods must be explicitly overloaded
In C #, if a programmer decides to overload a virtual method, he or she must explicitly use the Override keyword.
Let's examine the benefits of doing so. Assuming company a wrote a window class, Company B purchased a copy of the window class of company A as the base class. The programmer of Company B derives from the idea that ..., which is clearly derived from the following terms. In fact, there is a "combination" (also referred to as "embedding" or "containment" (COM semantics), etc.) in the way that the class is used, and the latter does not have the problem described below "the ListBox class and the RadioButton class." The programmer of Company B does not know or cannot control the design of the window class, including any future modifications that company A may make to the window class.
Now assume that company B's programmer decides to add a sort method to the ListBox class:
public class Listbox:window
{
public virtual void Sort () {}
}
This is no problem-until company A's window class author publishes version 2 of the window class, the company a programmer adds a public sort method to the window class:
public class Window
{
public virtual void Sort () {}
}
In C + +, the new virtual method sort of the window class will be used as the base class method for the ListBox virtual method. When you try to call the sort of window, the sort of the listbox is actually called. Virtual methods in C # "the original written virtual function" is always considered the root of the fictitious schedule. This means that as long as C # finds a virtual method, it will no longer look further along the inheritance hierarchy, and if a new sort virtual method is introduced into the Window,listbox, the run-time behavior will not be changed. When the listbox is compiled again, the compiler issues the following warning:
If you want to enable the current Member overload implementation, you can add the override keyword. Otherwise, add the New keyword.
If you want to remove this warning, the programmer must clearly indicate his intention. You can mark the sort method of the ListBox as new to indicate that it is not an overload of the virtual method of window:
public class Listbox:window
{
Public new virtual void Sort () {}
}
This way the compiler will not warn you again. On the other hand, if the programmer wants to overload the Windows method, simply add the override keyword explicitly.
Trap Seven: Can not initialize on the head
Initialization in C # is different from C + +. Suppose you have a class person, it has a private member variable of age; A derived class employee, which has a private member variable Salaryleverl. In C + +, you can initialize the SalaryLevel in the member initialization list section of the employee constructor:
Employee::employee (int theage, int thesalarylevel):
Person (theage)//Initialize base class
SalaryLevel (thesalarylevel)//Initialize member variable
{
Constructor body
}
In C #, this constructor is illegal. Although you can still initialize the base class like this, initializing a member variable will result in a compile-time error. You can assign an initial value to a member variable declaration:
Class employee:public Person
{
Here's the statement.
Private SalaryLevel = 3; Class
}
"The above code is wrong lc#, the correct wording is as follows:
Class Employee:person
{
private int salarylevel = 3;
}
】
You do not need to append a semicolon to each class declaration. Each member must have an explicit access-level declaration.
Trap 8. Cannot convert Boolean value to integer value
In C #, a Boolean value (True, false) differs from an integer value. Therefore, it cannot be written like this:
if (Somefuncwhichreturnsavalue ())//"I suppose this method does not return a Boolean value"
Nor can I expect if Somefuncwhichreturnsavalue returns a 0 it will be equal to false, otherwise true. The good news is that the old habits of misusing assignment operators instead of equality operators won't happen again. So, if you write this:
if (x = 5)
A compile-time error will be obtained because the result of x = 5 is 5, and it is not a Boolean value.
"The following is a logical error in C + + inadvertently, the compiler will not have any hint L run smoothly, but the result is not what you want:
C++:
#include "stdafx.h"
int main (int argc, char* argv[])
{
int n = 0;
if (n = 1)//Compiler Nothing said L General Recommendation Write 1 = n, in case of writing 1 = N compiler does not agree with J
{
printf ("1\n");
}
Else
{
printf ("0\n");
}
return 0;
}
The above run result is 1, this is not necessarily what you want.
C#:
Using System;
public class Rytestboolapp
{
public static void Main ()
{
int n = 0;
if (n = 1)//compiler does not agree that J cannot convert int to bool
{
Console.WriteLine ("1");
}
Else
{
Console.WriteLine ("0");
}
}
}
But if this is the case:
BOOL B = false;
if (b = true)
...
No, C + + or C # didn't recruit L.
】
C + + programmers generally like this kind of free writing:
if (MYREF)
if (MYINT)
But in C #, you have to write:
if (myref!= null)//or if (null!= myref)
if (MyInt!= 0)//or if (0!= MyInt)
Wait
】
Trap Nine. The switch statement cannot be "run through": That is, fall Through,beta2 's online documentation is the way to translate "
In C #, if there is code in the case statement, it cannot be "run through" to the next sentence. Therefore, although the following code is legal in C + +, it is not in C #:
Switch (i)
{
Case 4:
Callfuncone ();
Case 5://Error, cannot be "run through"
Callsomefunc ();
}
To achieve this, you need to explicitly use the goto statement:
Switch (i)
{
Case 4:
Callfuncone ();
Goto Case 5;
Case 5:
Callsomefunc ();
}
If the case statement does nothing (there is no code in it), it can be "run through":
Switch (i)
{
Case 4://Can be "run through"
Case 5://Can be "run through"
Case 6:
Callsomefunc ();
}
The following is a complete example of using switch, which also shows that the parameter type of the switch statement can be a string, and this example also demonstrates how to use the property.
Using System;
Class Ryswitchtest
{
Public Ryswitchtest (String AStr)
{
This. Strproperty = ASTR;
}
protected string Strfield;
public string Strproperty
{
Get
{
return this. Strfield;
}
Set
{
This. Strfield = value;
}
}
public void Switchstrproperty ()
{
Switch (this. Strproperty)
{
Case ("Ry01"):
Console.WriteLine ("Ry01");
Break
Case ("ry02"):
Console.WriteLine ("Ry02");
break;//If this line is commented out, the compiler will report that control cannot be run through another label from a case label (case "ry02":), if you really need to, you can write this: Goto ("ry03") or goto default.
Case ("ry03"):
Console.WriteLine ("Ry03");
Break
Default
Console.WriteLine ("Default");
Break
}
}
}
Class Ryswitchtestapp
{
public static void Main ()
{
Ryswitchtest rst = new Ryswitchtest ("ry02");
Rst. Switchstrproperty ();
}
}
】
Trap 10. C # requires an explicit assignment operation
C # requires explicit assignment operations, which means that all variables must be assigned before they can be used. Therefore, although you can declare a variable that is uninitialized, it cannot be passed to the method until it has a value.
This leads to a problem-when you simply want to use a variable as a "out" parameter passed to the method by reference. For example, suppose you have a method that returns the current hour, minute, and second. If you write this:
But this is too stupid! Our intention is simply to pass these variables to the gettime by reference, changing their values in them. To solve this problem, C # provides an out parameter modifier. This modifier avoids the need to initialize the reference parameter as well. For example, the arguments provided for gettime do not provide any information to the method, they simply want to get information from the method. Therefore, the need to initialize them outside of the method is avoided by marking these three parameters as out types. But when returned from the method passed in, the out parameter must be assigned. The following is the changed gettime parameter declaration:
public void GetTime (out int h, out int m, out int s)
{
h = Hour;
m = Minute;
s = Second;
}
The following is a new way to invoke the GetTime method:
Timeobject.gettime (out of Thehour, out of Theminute, out Thesecond);
The complete example is as follows:
c#:[Example 1: Method parameters decorated with ref]
Using System;
Class Ryreftest
{
Public Ryreftest ()
{
This. Intfield = 1;
This. Strfield = "Strfield";
}
protected int Intfield;
protected string Strfield;
public void GetFields (ref int aint, ref string AStr)
{
aint = this. Intfield;
AStr = this. Strfield;
}
}
Class Ryreftestapp
{
public static void Main ()
{
Ryreftest RRT = new Ryreftest ();
int Intvar = 0;//if it is int intvar; The compiler will report a variable with an unassigned value Intvar
String Strvar = "0";//if String Strvar; The compiler will report a variable with an unassigned value Strvar
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.