Deep Exploration C ++ object model Reading Notes (7)

Source: Internet
Author: User
Tags doxygen wxwidgets
Deep Exploration C ++ object model Reading Notes (7 ).

* ** Template's "active" behavior ***

Any member in template class can only be accessed or operated through an entity of template class.

 Point<float>::Status s;  // ok
Point::Status s;  // error

If we define a pointer pointing to a specific object, like this:

 Point<float> *ptr = 0;

Because this is a pointer to a Class Object and is not a class object, the compiler does not need to know any members data related to this class. Therefore, it is unnecessary to present a "point float object.

If it is not a pointer but a reference, assume:

 Point<float> &ref = 0;

The true semantics of this definition will be extended:

// Internal extension
Point <float> temp (float (0 ));
Point <float> & ref = temp;

The above conversion is because reference is not synonymous with no object. 0 is regarded as an integer and must be converted to an object of the point type <float>.

However, only when member functions is used, C ++ standard requires them to be "available. There are two main reasons for this rule:

(1) consider space and efficiency. It takes a lot of time and space to "present" unused functions;

(2) unimplemented functions. Not all types of a template can fully support a group of member functions, so you only need to have the actually needed member functions.

For example:

 Point<float> *p = new Point<float>;

Only float instances of (a) Point Template, (B) New operator, and (c) default constructor need to be "active ".

Keywords: malloc wxWidgets OpenGL polymorphism doxygen Deep Exploration C ++ object model Reading Notes (7 ).

* ** Error Report of template ***

All type-related checks, if the template parameter is involved, must be delayed until the actual active operation occurs.

For the following template declaration:

 template <class T>
class Mumble
{
public:
Mumble(T t = 1024) : _t(t)
{
if(tt != t)
throw ex ex;
}
private:
T tt;
}

Such as "t = 1024" and "TT! = T "potential errors will not be reported during template declaration, but will be checked and recorded when each current operation occurs, the result varies according to the actual type.

Mumble <int> Mi; // none of the above two potential errors exist
Mumble <int *> PMI; // "t = 1024" error because a non-zero integer constant cannot be assigned to a pointer

* ** Method of name resolution in template ***

The following two meanings are distinguished: one is the "scope of the template definition", the other is the "scope of the template instantiation ", that is, the program that "has a template.

 // scope of the template definition
extern double foo(double);

template <class type>
class ScopeRules
.{
public:
void invariant() { _member = foo(_val); }
type type_dependent() { return foo(_member); }
// ...
private:
int _val;
type _member;
};

// scope of the template instantiation
extern int foo(int);

ScopeRules<int> sr0;

Keywords: malloc wxWidgets OpenGL polymorphism doxygen Deep Exploration C ++ object model Reading Notes (7 ).

In "Scope of the template definition", only one Foo () function declaration is located within the scope; however, in "Scope of the template instantiation", two Foo () all function declarations are within the scope. Perform the following functions:

 // scope of the template instantiation
sr0.invariant();

So which Foo () function entity is called in invariant?

In the template, the resolution result for a nonmember name is determined based on whether the use of this name is related to the "parameter type used to reflect the template". If the use of this name is irrelevant, the name is determined by "Scope of the template definition". Otherwise, the name is determined by "Scope of the template instantiation.

// Because the _ Val type is int, the function resolution is only related to the function prototype, and has nothing to do with the function return value.
// The Real Type of the template has no effect on the _ Val type.
_ Member = Foo (_ Val );

Therefore, the call operation is determined by "Scope of the template definition.

For the following function calls:

Sr0.type _ dependent ();

Because the _ member type is related to the template parameter, it is determined by "Scope of the template instantiation.

* ** Current behavior of the member function ***

It is the only efficient way to manually complete the cash-in operation in individual object modules.

* ** Type identification during execution ***

The dynamic_cast operator can determine the real type during the execution period. If downcast is secure (that is, a base type Pointer Points to a derived class Object), this operator returns a pointer that has been properly transformed. If downcast is not secure, this operator returns 0.

Keywords: malloc wxWidgets OpenGL polymorphism doxygen Deep Exploration C ++ object model Reading Notes (7 ).

 typedef type *ptype;
typedef fct *pfct;

simplify_conv_op(ptype pt)
{
if(pfct pf = dynamic_cast<pfct>(pt)) {
...
}
else { ... }
}

What is the real cost of dynamic_cast? A type descriptor of pfct will be generated by the compiler, which must be obtained through vptr during the execution period. Possible conversions are as follows:

// Obtain the PT type descriptor
(Type_info *) (Pt-> vptr [0])-> _ type_description;

Type_info is the class name of the type descriptor defined by C ++ standard, which contains the type information to be calculated. The first slot of virtual table contains the address of type_info object, which is related to the class type referred to by PT.

The dynamic_cast operator is also applicable to reference. However, for a non-type-safe-cast operator, the result is not the same as that for pointers. A reference cannot "set itself to 0 to no object" as a pointer. If you set a reference to 0, A temporary object (having the referenced type) is generated. The initial value of the temporary object is 0, and the reference is set as an alias of the temporary variable.

Therefore, if the reference is not really a derived class, you can handle it by throwing a bad_cast exception:

 simplify_conv_op(const type &rt)
{
try {
fct &rf = dynamic_cast<fct&>(rt);
}
catch(bad cast) {
// ...
}
}

Of course, you can also use the typeid operator to achieve the same purpose:

 simplify_conv_op(const type &rt)
{
if(typeid(rt) == typeid(fct))
{
fct &rf = dynamic_cast<fct&>(rt);
}
else { ... }
}

 

Series of articles:

Deep Exploration C ++ object model Reading Notes (1)

Deep Exploration C ++ object model Reading Notes (2)

Deep Exploration C ++ object model Reading Notes (3)

Deep Exploration C ++ object model Reading Notes (4)

Deep Exploration C ++ object model Reading Notes (5)

Deep Exploration C ++ object model Reading Notes (6)

Last reading note of Deep Exploration C ++ Object Model

 

Related Article

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.