"Effective C + +" study notes-clause 32

Source: Internet
Author: User
Tags assert

*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************


Vi. inheritance and object-oriented design
Six, inheritance and object-oriented Design


Object-Oriented programming (OOP) is almost two years old, and even if you used to program only C, there is no way to escape this trend.
This chapter focuses on the differences between C + + OOP and the oop you might be accustomed to:
> Inheritance enables single inheritance or multiple inheritance
> Each inheritance connection can be public,protected or private, or virtual or non-virtual
> Individual options for member functions: virtual? Non-virtual? Pure virtual? and the interaction of member functions and other language features: what is the interaction between the default parameter values and the virtual function.
> There are others, such as: How does inheritance affect the name lookup rules of C + +? What are the design options? If the behavior of class needs to be modified, is the virtual function the best choice?

In addition to these, this chapter will explain the true meaning of the various features of C + +. For example:
> "Public inheritance" means "is-a"
The > virtual function means "interfaces must be inherited"; the non-virtual function means "interfaces and implementations must be inherited"
wait



Clause 32: Determine your public inheritance mold out is-a relationship
Rule 32:make sure public inheritance models "IS-A"



1.public Inheritance and Is-a
One of the most important rules for object-oriented programming in C + + is that public inheritance (open inheritance) means the relationship of "is-a"
If you make Class D ("Derived") Inherit Class B ("Base") as public, you are telling the C + + compiler (or someone who looks at your code) that each object of type D is also an object of type B, and vice versa.
For example:

Class person  {  ...  }; Class Student:public person  {  ...  };

The code above says--Every student is human, but not everyone is a student. This is is-a.

In the C + + realm, any function that expects to have an argument of type person (or Pointer-to-person or Reference-to-person) are also willing to accept a Student object (or Pointer-to-student or reference-to-student):

void Eat (const person& p);    Anyone would eat void study (const student& s);    Only students who come to school to study person p;    P is human student s;    S is student eat (p);    Ok,p is a person who can perform eating this action eat (s);    Ok,s is a student, according to Is-a, can perform eating this action study (s);    Ok,s is a student, can carry on to school to study this action study (p);    No! P is a person, not everyone can carry out to school to learn this action

> This argument is only for public inheritance to be set up < for private inheritance, will be completely different, see clause 39, as for protected inheritance, the author also did not make too clear ...




2. Various problems arising
the equivalence between >1 public inheritance and is-a sounds very simple, but can sometimes be misleading , such as: Penguins are a kind of bird, birds can fly, but if we describe this relationship in such a way:

Class Bird  {public:  virtual void fly ();    Birds can fly ...  }; Class Penguin:public Bird  {    //Penguin is a kind of bird ...  };

boom! What's going on? What are our three viewpoints?
Obviously, this is wrong, and we have to admit that there are several kinds of birds that can't fly.
But how do we mean to react?
①, like the following inheritance system, can accurately reflect our meaning:

Class Bird  {      ...    No declaration of the fly function};class flyingbird:public Bird  {public:  virtual void fly ();  ...}; Class Penguin:public Bird  {  ...};

but is it over now? No no no, because for some software systems, it may not be necessary to distinguish between flying birds and flightless birds. If your program is more interested in bird's beak and bird's fin and doesn't care about flying at all, then the new "Double Class inheritance system" may be sufficient.
> This actually illustrates the fact that there is no perfect design for all software in the world; so-called best design depends on what the system wants to do. <
② There is another way to more accurately reflect our ideas. Redefine the fly function for penguins so that it produces a run-time error.

void error (const std::string& msg), class Penguin:public Bird  {public:  virtual void Fly ()  {  error ( "Attempt to make a Penguin fly!");  }  ...};

Some of the things here may be different from what you think, and this is not to say "Penguins can't fly", but "penguins fly, but trying to do that is a mistake"!
③ the difference between the two, from the point of time when the error was detected: "Penguins do not fly" this restriction can be enforced by the compilation period, but if it violates the "penguin can fly, but try to do it is wrong" this rule, only the runtime can be detected.
>2 class Square should inherit class Rectangle with public?
Of course, that's what the school says--the square is a special rectangle.
However, take a look at the following code:

Class Rectangle  {public:  virtual void setheight (int newheight);  virtual void setwidth (int newwidth);  virtual int height () const;    Returns the current value  virtual int width () const;  ...}; void Makebigger (rectangle& r) {  int oldheight = R.height ();  R.setwidth (R.width () +10);    The width of R is added to the  assert (R.height () ==oldheight);    Determine if the height of R has never changed}

Obviously, the above assert result is always true. Since Makebigger only changes the width of R, the height of R has never been changed.
Then:
Class Square:public Rectangle  {  ...  }; Square S;...assert (S.width () ==s.height ());    This must be true for all squares makebigger (s);                    Because public inherits, S is a (is-a) rectangle assert (S.width () ==s.height ());    For all the squares should still be true

It is also clear that the second assert result should always be true. Because by definition, the height and width of the square are the same.
But how do we adjust the following assert judgments?
? S is the same height and width before calling Makebigger
? Within the Makebigger function, the width of S is changed, but the height is constant
? After Makebigger returns, the height of S is again the same as its width. (Note that S is passed to Makebigger by reference, so Makebigger modifies the s itself, not the copy of s)
In fact, the fundamental difficulty of this example is that certain things that can be done with a rectangle (for example, the width can be modified independently of its height by the outside world) cannot be applied to the square body (the width should always be the same as the height).
However, the public inherits the proposition that everything can be done on the base class object, and everything may be implemented on derived class.
and the most important point: ☆ Code by compiling does not mean that it can operate properly ☆




3. Finally
Is-a is not the only relationship that exists in class. Another two common relationships are has-a (with one) and is-implemented-in-terms-of (based on physical implementation).
It is not uncommon in C + + to mistakenly portray any of these important relationships as is-a, so you should be sure you understand the difference between these "class interrelationships" and know how to best shape them in C + +.



★ Please remember ★
? "Public inheritance" means is-a. Everything that applies to base class must also apply to derived class, because each derived class object is also a base class object.





*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************

"Effective C + +" study notes-clause 32

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.