Several small issues worth analyzing in C + + (2)

Source: Internet
Author: User

Here are 3 small questions, as C + + beginner You must know where the mistake is.

1. A reference to a base class or a pointer conversion of a derived class must be "perfect"?

In general, you will most likely think that it is normal for a reference or pointer to a derived class object to be converted to a reference or pointer to a base class object. What if it's not a normal situation? Take a look at the following example:

classperson{ Public: Person (Const string& str ="Normal Person"): ID (str) {}stringID;//as a general human being "normal", as a student is "student"};classStudent:Privateperson{ Public: Student (Const string& str ="Student"): Person (str) {}};

It is still an example of ordinary people and students who are private and derive from ordinary people. The ID represents the identity status (which I declare as public, for convenience only, and I still strongly recommend declaring private).

void Printid (const person& p)            // print ID{    << p.id << Endl;}

I have the following call:

Person p; Student s; Printid (p);             // Okay, no problem . Printid (s);            // compilation Error

OK, I've already commented on it. Compile error, error message: Error C2243: "Type conversion": The conversion from "Student *" to "Const person &" exists but cannot be accessed. Is it a little bit different from what you think?

Analysis:

Many times, we all default to public inheritance, publicinheritance outlines a kind of is-a , that is, the derived class is a base class, from this semantic understanding seems to be converted from the derived class to the base class automatic (reference or pointer mode). What I'm talking about here is private inheritance, andprivate succession outlines a relationship that is "realized by something" . Suppose D is derived from B with private, meaning that D can be obtained from the implementation of the B object. The compiler does not automatically convert derived class objects to base class objects.

Another point of doubt, you may have noticed Printid. If the student object is passed in, it seems that the private member ID is accessed, does this cause a compilation error? Let's change it to the following:

void Printid (const person& p)            // Print ID{    "ID Infor" << Endl; //     cout << p.id << Endl;}

Same compilation error. Therefore, it is important to note that the reference or pointer conversion of a derived class to a base class must be "perfect", provided that public inheritance cannot be private or protected inheritance .

Note: also to add a note, in the class of inheritance hierarchy in the main, private sometimes in the design can provide a little "convenience", protected I do not know what good use for the time being.

2. Compile-time error caused by keyword typename.

This problem, many people may know, perhaps as I know the "incomplete." The first thing to make clear is that the keyword TypeName is exactly the same as class when declaring the template type parameter. What I'm actually talking about is the use of TypeName generics (templates), which is a big thing.

The name that appears within the template, if dependent on a template parameter, is called a subordinate name. If the subordinate name is nested within class, it is called a nested subordinate name.

Template <typename t>void printelement (const t& VEC) {    t::const_iterator* x;            //Const_iterator is a nested subordinate name ... }

We might think that a pointer was declared, pointing to a t::const_iterator. In fact, T::const_iterator may also be a static variable with the name Const_iterator, and the line above defines a multiplication. Therefore, nested subordinate names can cause parsing difficulties .

The C + + parser has a simple rule: when you encounter a nested subordinate name in the template, it assumes that the name is not a type, which is the default, unless you actively tell the compiler with the keyword typename.

Template <typename t>void printelement (const t& VEC) {    typename T::const_iterator ITER;             // This is the right statement. ...}

This piece of knowledge, basically everyone knows. What I'm actually trying to say is that when using TypeName, there are a few small points to note, because the position of TypeName is not only within the function. Like what:

Template <typename t>void Print (TypeName T::const_iterator iter)        // formal parameter list be sure to use TypeName 

Here's a more complicated example:

Template <classT>classBase { Public:    classNested { Public: Nested (inta): X (a) {}Private:        intx; };}; Template<classT>classDerived: Publicbase<t>::nested//inherit list, you can't use typename{ Public:    ExplicitDerived (intA): Base<t>::nested (a) {}//constructor Initialization list, you cannot use TypeName};

Note that the part of the comment in the code is typename two places that cannot be used. Let me expand on this again:

template<class t>void func (const TypeName base<t>::nested& test)            // using TypeName, very good {    "Very good" << Endl;            }

What I want to ask is:derived<int> D (5); How do I call that function? The correct strategy is:

func<int> (d);                // the correct func (d);                    // of the wrong

Incorrect usage, the compiler will remind you that T cannot be resolved.

3. Can the constructors and destructors be virtual functions? Can constructors and destructors call virtual functions?

This little problem has a long history. Do you have all the answers? I don't bother to say it. (I did not collect all the statements, that is, my own understanding)

(1) can the constructor and destructor function as virtual functions?

The constructor cannot be a virtual function.

Answer: There are several points to be said, I am not full of words.

1, the function of virtual function is mainly for the execution period according to the base pointer addressed to the "correct" function. Since the implementation period, it must have crossed the compilation period, it is bound to set up the object, the constructor is initialized to use, it is necessary to construct the function.

2, if I remember correctly, the constructor has a function is to establish a vptr, note is not VTBL (compile time to fix), assuming that the virtual function, who to establish vptr, the constructor should be in the VTBL.

3, virtual function is for the derived class to transform it, but the constructor can not be inherited, talk about how to transform.

Wait a minute...

Can a destructor be a virtual function?

If you do not make a derivative class like STL, I advise you not to think of it as a virtual function, Vptr is also 4 bytes of storage. If you want it as a derived class, I advise you to set it as a virtual function, otherwise the memory leak will find you.

(2) constructor, destructor can call virtual function?

In fact, I have never understood the meaning of this problem. constructors, destructors call virtual functions, but the version of the owning class is called.

Directory:

Several small issues worth analyzing in C + + (1)

Several small issues worth analyzing in C + + (2)

Several small issues worth analyzing in C + + (2)

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.