RTTI application: Let's cast

zhaozj2021-02-11  153

I have learned RTTI very early, but I have not used it,

For example, in the MFC application, getdlgitem () returns a CWnd *, but everyone is usually directly Cast, CEDITCTRL * P = (CEDITCTRL *) getDlgitem (IDC_EDIT);

Everyone has learned this grammar, and I am also the case.

Because when I want to use RTTI, I don't think so convenient, my heart is always uncomfortable.

CEDITCTRL * PEDIT = Dynamic_cast (Getdlgitem (IDC_EDIT));

I always feel clearly that it is CEDITCTRL *, but it will be checked at runtime, there is so uncomfortable, but if you use C grammar, you don't meet the standard C Style, which has been lazy method,

Template DESTTTTYPE SAME_HIERARCHY_CAST (SRCTYPE SRC) {Assert (Dynamic_cast (src)); return static_cast (src);

This function can be used in Cast in a system.

CEDITCTRL * PEDIT = SAME_HIERARCHY_CAST (Getdlgitem (IDC_EDIT));

This ensures that the runtime check can be assured in the Debug version, ensuring whether there is a viable conversion, and SRC is not null), and in the Release version (only static_cast) is removed (STICAST).

After all, the Debug version is running correctly, there is no reason to be included in the Release version.

It should be noted that this CAST does not support crossing Cast, ie

Struct B {Virtual ~ b ()}};

Struct D1: B {}; structure D2: b {}; struct d: D1, d2 {};

Void F1 (D2 * PD2) {// compile error D1 * PD1 = Same_Hierarchy_Cast (pd2);

The reason for compiling errors is very simple, because STATIC_CAST itself does not support spanning casual. :)

Change this.

// d1 * pd1 = Same_Hierarchy_cast (pd2);

This uses an IMPLICIT Conversion from D * to D1 *,

From the above class structure, you can also find such a problem.

VOID F2 (B * PB) {// D1 * PD1 = Same_Hierarchy_Cast (pb);}

// d2 * pd2 = new d; f2 (PD2);

This is a very deep error, and there is actually 2 B objects in the D object.

The PB (b *) in F2 () is from the PD2 (D2 *) Implicit Conversion, so

D1 * PD1 = DYNAMIC_CAST (PB); can span the D1 sub-object included in D1 to PB,

D1 * PD1 = static_cast (pb); there is no such ability (here the compiler considers PB pointing to a B child object in PD1, rather than by PD2, classic errors). The value obtained above is different, but the compiler will not give you any prompts.

It seems that there is nothing good method to solve this problem, in the case of multiple inheritance, it is recommended to use Dynamic_Cast.

Dr. BS believes that mandatory is one of the ugliest features in C, as this, a bunch of Cast is provided in C to replace it (each for different situations). Standard C is absolutely not recommended for C style, but I find it inseparable from it.

such as:

B * PB = New D;

Here, the compiler will report a mistake, Ambiguous, it doesn't know where to convert, usually most of the programmers (including me) will write this:

B * PB = (D1 *) New D; or b * pb = (d2 *) new D;

Dynamic_cast is used here is purely waste, static_cast? I feel very good. Because this is only implicit conversion, it is not necessary to force, how can it make it more natural, of course, you can:

D1 * pd1 = new d; b * Pb = D1;

This is not too much. . . ? ?

I feel that there is only a keyword to add implicit conversions in C to eliminate the C style enforcement. Fortunately, this feature can be easily implemented.

Template DESTTTYPE IMPLICIT_CAST (SRCTYPE SRC) {Return Src;}

So, the example can be written:

B * PB = IMPLICIT_CAST (New D);

oral

B * PB = IMPLICIT_CAST (New D);

In this way, even if the relationship between D, D1, D2 changes (if there is no parent child relationship), the compiler will immediately report an error, and the former, you will not know anything until the program crashes.

转载请注明原文地址:https://www.9cbs.com/read-5501.html

New Post(0)