Basic knowledge
Talk about 8 years of experience in C ++ object-oriented design
Talk about 8 years of experience in C ++ object-oriented design
Category Tags: C ++
Six years ago, when I first fell in love with Object-Oriented, I remembered almost ten definitions in one breath. Six years later, when I rolled out of hundreds of thousands of lines of programs and prepared to write a dim sum, I couldn't explain what "object-oriented" was, as if it wasn't clear what mathematics was. The buzzwords "object-oriented analysis" and "object-oriented design" in software engineering are usually for the "requirements analysis" and "system design" links. There are several college schools of "object-oriented", such as the Buddha, God, and Allah who define the world in their own way, and leave a pile of scriptures to explain the world.
学者 Some scholars suggest to find “objects” this way: analyze the grammar of a sentence, find out the nouns and verbs, the nouns are the objects, and the verbs are the methods (ie functions) of the objects.
为了 In order to fight against Mao Zedong's Qinyuan Spring · Snow, the Kuomintang writers specially asked the Qing Dynasty elders to write some poems that were neat and neat. Lao Jiang yelled angrily: "Niangxipi, all have the smell of carrion in the coffin." I looked at thousands of pages of software engineering materials and finally found myself somewhat "mentally retarded" and unable to understand "object oriented" Theory, while waking up to "programming is the last word."
很多 There are many object-oriented programming languages, such as Smalltalk, Ada, Eiffel, Object Pascal, Visual Basic, C ++ and so on. The C ++ language is most flattering because it is compatible with C and has the performance of C. In recent years, a pure object-oriented language called Java has become popular, and many people are yelling to use Java to revolutionize C ++. I think Java is like a nephew of C ++. Although not directly inherited, it is also quite decent. Nephew spilled a pee while playing on her body, and the two shouldn't argue about it.
借 There are many books about C ++ programming. This chapter does not talk about the syntax of C ++, but only some small programming principles. If I can understand these little things a few years ago, I can greatly improve the quality of hundreds of thousands of lines of programs.
1. Important concepts of C ++ object-oriented programming
There is such a role in the early revolutionary films. He said: "I am the party's representative, I represent the party, and I am the party." Later he brought disaster to the comrades.
的 A programmer who knows C ++ must know object-oriented programming?
的 A programmer who doesn't use C ++ must not know object-oriented programming?
Both are not necessarily. Just as bad guys may not be good guys after joining the party, and good guys may not become bad guys without joining the party.
I'm not afraid to offend the rage and say a big word: "C ++ has no masters, only C has masters." After 8 years of programming in C and C ++, I deeply regret that I am not a master of C, and regret that no one asked me Object-oriented programming. Like many C ++ programmers, when I enjoy the benefits of C ++ syntax, I think I understand object-oriented programming. Just like squeezing out the toothpaste and selling the toothpaste skin, it's a ruthless thing.
People can speak Mandarin if they don't understand Pinyin, and they can speak Mandarin better if they know Pinyin. If you don't understand object-oriented programming, you can also use C ++ programming. If you know object-oriented programming, you will make C ++ programs better. This section describes three very basic concepts: "classes and objects", "inheritance and composition", "virtual functions and polymorphism". Understanding these concepts can help improve the quality of your programs, especially "reusability" and "extensibility."
1.1 Classes and objects
Object is an instance of a class. If you compare the object to a house, the class is the design drawing of the house. So the focus of object-oriented programming is the design of classes, not the design of objects. Classes can encapsulate data and functions, where functions represent the behavior (or service) of the class. Classes provide keywords public, protected, and private to declare which data and functions are public, protected, or private.
This can achieve the purpose of information hiding, that is, let the class only disclose the content that must be known to the outside world, and hide everything else. We must not abuse the encapsulation function of the class, don't treat it as a hot pot, throw everything into it.
Is the design of tadpoles data-centric or behavior-centric?
The group that advocates "data-centric" concerns the internal data structure of the class. They are used to writing private data in the front and public functions in the back, as shown in Table 8.1 (a).
The group that advocates "behavior-centric" is concerned about what kind of services and interfaces a class should provide. They are used to writing public types of functions first and private types of data later, as shown in Table 8.1 (b) As shown.
Talk about 8 years of experience in C ++ object-oriented design
Many C ++ textbooks advocate "data-centric" when designing classes. I insist and recommend that readers be "behavior-centric" when designing classes, that is, first consider what functions a class should provide. The core of Microsoft's COM specification is interface design. COM's interface is equivalent to the public function of a class [Rogerson 1999]. In terms of programming, let's not doubt Microsoft's style.
It is relatively easy to design isolated classes. The hard part is to design the base classes and their derived classes correctly. Because some programmers are confused about the concepts of "Inheritance", "Composition", "Polymorphism".
1.2 Inheritance and composition
If A is a base class and B is a derived class of A, then B will inherit A's data and functions. The sample program is as follows:
C ++ code
class A
{
public:
void Func1 (void);
void Func2 (void);
};
class B: public A
{
public:
void Func3 (void);
void Func4 (void);
};
// Example
int main ()
{
B b; // an object of B
b.Func1 (); // B inherits function Func1 from A
b.Func2 (); // B inherits function Func2 from A
b.Func3 ();
b.Func4 ();
return 0;
}
简单 This simple example program illustrates the fact that C ++ 's "inheritance" feature can improve program reusability. Just because "inheritance" is too useful and easy to use, we should prevent "inheritance" from being used arbitrarily. We need to establish some rules of use for "inheritance":
First, if class A and class B have nothing to do with each other, you cannot make B inherit the functions of A in order to make B more functional.
Don't feel "don't eat white and don't eat", let a good and healthy young man eat ginseng for no reason.
Second, if it is necessary for class B to use the function of A, there are two cases to consider:
(1) If B is logically a kind of A, then B is allowed to inherit the functions of A. For example, Man is a kind of Human, and Boy is a kind of Man. Then the class Man can be derived from the class Human and the class Boy can be derived from the class Man. The sample program is as follows:
C ++ code
class Human
{
...
};
class Man: public Human
{
...
};
class Boy: public Man
{
...
};
(2) If A is logically a "part of" B, then B is not allowed to inherit the functions of A, but B must be combined with A and other things. For example, Eye, Nose, Mouth, and Ear are part of the Head, so the class Head should be a combination of the Eye, Nose, Mouth, and Ear classes, not derived. The sample program is as follows:
C ++ code
class Eye
{
public:
void Look (void);
};
class Nose
{
public:
void Smell (void);
};
class Mouth
{
public:
void Eat (void);
};
class Ear
{
public:
void Listen (void);
};
// Proper design, lengthy procedures
class Head
{
public:
void Look (void) {m_eye.Look ();}
void Smell (void) {m_nose.Smell ();}
void Eat (void) {m_mouth.Eat ();}
void Listen (void) {m_ear.Listen ();}
private:
Eye m_eye;
Nose m_nose;
Mouth m_mouth;
Ear m_ear;
};
If Head is allowed to be derived from Eye, Nose, Mouth, and Ear, then Head will automatically have the functions of Look, Smell, Eat, Listen:
C ++ code
// wrong design
class Head: public Eye, public Nose, public Mouth, public Ear
{
};
The above procedure is very short and works correctly, but this design is wrong. Many programmers can't stand the temptation to "inherit" and make design mistakes.
Do you know why?
Because the hen laid duck eggs.
1.3 Virtual functions and polymorphism
In addition to inheritance, another good feature of C ++ is its support for polymorphism, which allows objects of derived classes to be used as objects of the base class. If A is a base class and B and C are derived classes of A, the parameter of the polymorphic function Test is a pointer to A. Then the Test function can reference objects of A, B, and C. The sample program is as follows:
C ++ code
class A
{
public:
void Func1 (void);
};
void Test (A * a)
{
a-> Func1 ();
}
class B: public A
{
...
};
class C: public A
{
...
};
// Example
int main ()
{
A a;
B b;
C c;
Test (& a);
Test (& b);
Test (& c);
return 0;
};
The above program can't see the value of "polymorphism". After adding virtual functions and abstract base classes, the power of "polymorphism" is displayed.
C ++ uses the keyword virtual to declare a function as a virtual function. The virtual function of the derived class will override the function of the virtual function corresponding to the base class. The sample program is as follows:
C ++ code
class A
{
public:
virtual void Func1 (void) {cout << “This is A :: Func1 \ n”}
};
void Test (A * a)
{
a-> Func1 ();
}
class B: public A
{
public:
virtual void Func1 (void) {cout << “This is B :: Func1 \ n”}
};
class C: public A
{
public:
virtual void Func1 (void) {cout << “This is C :: Func1 \ n”}
};
// Example
int main ()
{
A a;
B b;
C c;
Test (& a); // Output This is A :: Func1
Test (& b); // Output This is B :: Func1
Test (& c); // Output This is C :: Func1
return 0;
};
If base class A is defined as follows:
C ++ code
class A
{
public:
virtual void Func1 (void) = 0;
};
The function Func1 is called a pure virtual function, and the class containing pure virtual functions is called an abstract base class. The abstract base class only needs to define the form of pure virtual functions, and the specific functions are implemented by derived classes.
The combination of "abstract base class" and "polymorphism" has the following outstanding advantages:
(1) The application does not have to write function calls for each derived class, it only needs to process the abstract base class. This
Called "changing with constant change" can greatly improve the reusability of the program (this is the reuse of interface design, not the reuse of code implementation).
(2) The function of the derived class can be referenced by the base class pointer. This is called backward compatibility and can improve the process.