CRTPред рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛ред Mixinред рд╡рд┐рд╖рдп рдкрд░ рд╡рд┐рдЪрд╛рд░

рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ, рдореИрдВ C ++ рдореЗрдВ рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛ рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд╛рд╕реНрддреБ рд╕рдорд╛рдзрд╛рдиред рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдореБрд╣рд╛рд╡рд░реЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ - CRTP ред рдореИрдВ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдореИрдВ MixIn рдХрдХреНрд╖рд╛рдУрдВ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ ред рдореИрдВ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЬреНрдЮрд╛рди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдЖрдк рдЕрдкрдиреЗ рд▓рд┐рдП рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдкрд░рд┐рдЪрдп


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, C ++ рдПрдХ рдмрд╣реБ-рдкреНрд░рддрд┐рдорд╛рди рднрд╛рд╖рд╛ рд╣реИред рдЖрдк рдЗрд╕ рдкрд░ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рднрд╛рд╖рд╛ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ, рдПрд╕рдЯреАрдПрд▓ рдФрд░ рдирдИ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ ( рд▓реИрдореНрдмреНрдбрд╛, рдПрд╕рдЯреАрдбреА :: рдлрд╝рдВрдХреНрд╢рди, рдПрд╕рдЯреАрдбреА :: рдмрд╛рдЗрдВрдб ) рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╡ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рд░рдирдЯрд╛рдЗрдо рдореЗрдВ, рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХрд╛ рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдЕрдкрдиреЗ рд╢реБрджреНрдз рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╣реИред
рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдХрд┐рд╕реА рднреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмрдбрд╝реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдЖрдк рд╕рдВрднрд╡рддрдГ рдЗрди рд╕рднреА рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдорд┐рд╢реНрд░рдг рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдХрдХреНрд╖рд╛рдУрдВ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдПрдХ рд╡рд╕реНрддреБ-рдЙрдиреНрдореБрдЦ рдкреНрд░рддрд┐рдорд╛рди, рдПрдХ рдЦреБрд▓рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдФрд░ рдмрдВрдж рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдЗрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди), рд╡рд┐рд░рд╛рд╕рдд, рдФрд░ рдЖрднрд╛рд╕реА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓рд╛рдЧреВ рдЧрддрд┐рд╢реАрд▓ рдмрд╣реБрд░реВрдкрддрд╛, рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рд╕рдмрд╕реЗ рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЧрддрд┐рд╢реАрд▓ рдмрд╣реБрд░реВрдкрддрд╛ рдореБрдХреНрдд рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдПрдХ рдЖрднрд╛рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдордп рдмрд╣реБрдд рдмрдбрд╝реА рдирд╣реАрдВ рд╣реИ, рдХреБрдЫ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЪрдХреНрд░ рдЬреЛ рдХрдИ рдмрд╣реБрд░рдВрдЧреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХрд╛ рдУрд╡рд░рд╣реЗрдб рд╕рд╛рдзрд╛рд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛


рдЬрдмрдХрд┐ рдЧрддрд┐рд╢реАрд▓ рдмрд╣реБрд░реВрдкрддрд╛ рд░рдирдЯрд╛рдЗрдо рдФрд░ рд╕реНрдкрд╖реНрдЯ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдмрд╣реБрд░реВрдкрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛ рд╕рдВрдХрд▓рди рд╕рдордп рдФрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдмрд╣реБрд░реВрдкрддрд╛ рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП

void process(base* b) { b->prepare(); b->work(); ... } 


рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ: рдкреНрд░рдХреНрд░рд┐рдпрд╛ () рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджрд┐рдП рдЧрдП рд╕реВрдЪрдХ рдХреЛ рдЙрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдЖрдзрд╛рд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рд╡рд┐рд░рд╛рд╕рдд) рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ , рдФрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреНрд░рд┐рдпрд╛рдиреНрд╡рдпрди рдХреЗ рджреМрд░рд╛рди рддреИрдпрд╛рд░реА () рдФрд░ рдХрд╛рд░реНрдп () рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЪрдпрди рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╕рдВрдХреЗрдд рдмреА ред

рдпрджрд┐ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ:

 template<typename T> void process(T t) { t.prepare(); t.work(); } 

рддрдм рд╣рдо рдпрд╣ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЯрд╛рдЗрдк T рдХреЗ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рддреИрдпрд╛рд░ () рдФрд░ рдХрд╛рдо () рдлрд╝рдВрдХреНрд╢рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рджреВрд╕рд░реА рдмрд╛рдд, рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╕рдВрдХрд▓рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдЯреА рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ ред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рднреА рдЕрдВрддрд░реЛрдВ рдХреЗ рд▓рд┐рдП, рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╣реБрд░реВрдкрддрд╛ рдХреЗ рдореБрдЦреНрдп (рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ) рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛрдб рдореЗрдВ рдХреБрдЫ рднреА рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдмрд╢рд░реНрддреЗ рдХрд┐ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░реЗрдВред

рдЪреВрдВрдХрд┐ рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рдЕрджреНрднреБрдд рд╣реИ, рдХреЛрдб, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рд░рдирдЯрд╛рдЗрдо рдУрд╡рд░рд╣реЗрдб рдХреЛ рд╕рдорддрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЧрддрд┐рд╢реАрд▓ рдмрд╣реБрд░реВрдкрддрд╛ рдХреЛ рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ? рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдорддреМрд░ рдкрд░ рд╣реЛрддрд╛ рд╣реИ, рдЪреАрдЬреЗрдВ рдЗрддрдиреА рд╕рд░рд▓ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред рд╕реНрдерд┐рд░ рдкреЙрд▓реАрдореЛрд░реНрдлрд┐рдЬреНрдо рдХреЗ рдХрдИ рдиреБрдХрд╕рд╛рди рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд╡реНрдпрдХреНрддрд┐рдкрд░рдХ рднреА рд╣реЛрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдмреНрдЬреЗрдХреНрдЯрд┐рд╡, рдпрд╣ рддрдереНрдп рд╣реИ рдХрд┐ рд╕реНрдкрд╖реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЕрдХреНрд╕рд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдЬреАрд╡рди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВред рдЖрдкрдХреА рдЖрдВрдЦреЛрдВ рдХреЗ рд╕рд╛рдордиреЗ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ - рдЬрд┐рд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЖрдкрдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣ рдЗрд╕ рдХреЛрдб рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреА рдХреЛрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдХреЛрдб рдХреЛ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рд╣реИред рдпрд╣ рднреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдХреЛрдб рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЕрдм рдпрд╣ рдкреВрдЫрдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕ рдпрд╛ рдЙрд╕ рдЯреБрдХрдбрд╝реЗ рдореЗрдВ рдХреНрдпрд╛ рдерд╛ред

рдЙрджреНрджреЗрд╢реНрдпрдкреВрд░реНрдг рдХрд╛рд░рдг, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рддрд░рд╣ рд╕реЗ рдпрд╛ рдЗрд╕ рддрдереНрдп рд╕реЗ рджреВрд╕рд░реЗ рдХреЛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐, рддрд╛рддреНрдХрд╛рд▓рд┐рдХрддрд╛ рдХреЗ рдмрд╛рдж, рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрдХреНрд╖рд╛рдПрдВ (рдлрд╝рдВрдХреНрд╢рди) рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рд╣реЛрддреЗ рд╣реИрдВ, рдЕрдХреНрд╕рд░ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдЬреБрдбрд╝реЗ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред
рдпрд╣ рдмреБрд░рд╛ рдХреНрдпреЛрдВ рд╣реИ? рдЕрддрд┐рд░рд┐рдХреНрдд рдЪрд╛рд▓ рдХреЗ рдмрд┐рдирд╛ рдЗрди рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдПрдВ ( рдмрдврд╝рд╛рд╡рд╛ рджреЗрдЦреЗрдВ :: рд╕рдВрд╕реНрдХрд░рдг, рдмрдврд╝рд╛рд╡рд╛ :: рдЯрдкрд▓, рдмрдврд╝рд╛рд╡рд╛ :: рдХрд┐рд╕реА рднреА, рдмрдврд╝рд╛рд╡рд╛ :: рдлреНрдпреВрдЬрди рдЖрджрд┐) рдХреЛ рдПрдХ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдирд╣реАрдВ рдбрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП рдмреИрдЪ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдпрд╣ рдЕрд╕рдВрднрд╡ рд╣реИ - рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рд╕рджрд╕реНрдп, рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде, "рд░рдгрдиреАрддрд┐" рдпрд╛ "рд╕реНрдерд┐рддрд┐" рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпреЗ рдкреИрдЯрд░реНрди рдЕрдиреНрдп рддрд░реАрдХреЛрдВ рд╕реЗ рднреА рдмрд┐рдирд╛ рд╡рд░реНрдЧ рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, std :: function рдпрд╛ рдмрд╕ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдЯреВ рдлрдВрдХреНрд╢рди, рдкреНрд░рддрд┐рдмрдВрдз, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЪреЗрд╣рд░реЗ рдкрд░ рд╣реИред

рд▓реЗрдХрд┐рди рдХреЛрдИ рднреА рд╣рдореЗрдВ рдХрд┐рд╕реА рдПрдХ рдкреНрд░рддрд┐рдорд╛рди рдХрд╛ рд╕рдЦреНрддреА рд╕реЗ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред OOP рдкреНрд░рддрд┐рдорд╛рди рдФрд░ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рддрд┐рдорд╛рди рдХреЗ рдЬрдВрдХреНрд╢рди рдкрд░ рдЗрди рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреЗ рдЬрдВрдХреНрд╢рди рдкрд░ рд╕рдмрд╕реЗ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА, рд▓рдЪреАрд▓рд╛ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рд╕рдорд╛рдзрд╛рди рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред CRTP рдореБрд╣рд╛рд╡рд░рд╛ рдРрд╕реЗ рдкреНрд░рддрд┐рдорд╛рдиреЛрдВ рдХреЗ рд╡рд┐рд▓рдп рдХрд╛ рд╕рд┐рд░реНрдл рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред

CRTP


CRTP (рдШреБрдВрдШрд░рд╛рд▓реЗ рдЖрд╡рд░реНрддреА рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрдЯрд░реНрди) рдПрдХ рдбрд┐рдЬрд╛рдЗрди рдореБрд╣рд╛рд╡рд░рд╛ рд╣реИ рдХрд┐ рдПрдХ рд╡рд░реНрдЧ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рд╕реЗ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИред рдпрд╣ рднреНрд░рд╛рдордХ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдб рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИред

 template <class T> class base{}; class derived : public base<derived> {}; 


рдпрд╣ рд╣рдореЗрдВ рдХреНрдпрд╛ рджреЗ рд╕рдХрддрд╛ рд╣реИ? рдпрд╣ рдбрд┐рдЬрд╛рдЗрди рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рд╕реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рддрдХ рдкрд╣реБрдВрдЪрдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред

 template<typename D> struct base { void foo() {static_cast<D*>(this)->bar();} }; struct derived : base<derived> { void bar(); }; 


рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдВрдЪрд╛рд░ рдХреА рд╕рдВрднрд╛рд╡рдирд╛, рдмрджрд▓реЗ рдореЗрдВ, рдХрдИ рджрд┐рд▓рдЪрд╕реНрдк рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдЦреЛрд▓рддреА рд╣реИред

рд╕реНрдкрд╖реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕


рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛ рдкрд░ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, рдореИрдВрдиреЗ рд╕реНрдкрд╖реНрдЯ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреА рдХрдореА рдХреЛ рд╕реНрдереИрддрд┐рдХ рдмрд╣реБрд░реВрдкрддрд╛ рдХреЗ рд╡реНрдпрдХреНрддрд┐рдкрд░рдХ рджреЛрд╖ рдХреЛ рдмреБрд▓рд╛рдпрд╛ред рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдХреЛрдИ рднреА рддрд░реНрдХ рджреЗ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд░рд╛рд╕реНрддрд╛ рдпрд╛ рджреВрд╕рд░рд╛, рд╕реНрдкрд╖реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ CRTP рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рджрд░рдЕрд╕рд▓, рд╣рдо рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рд╕реЗ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 template<typename D> struct base_worker { void work() {static_cast<D*>(this)->work_impl();} void prepare() {static_cast<D*>(this)->prepare_impl();} }; struct some_concrete_worker : base_worker<some_concrete_worker> { void work_impl(); //     void prepare_impl(); //    }; template<typename Worker> void polymorhic_work(const Worker& w) { w.prepare(); w.work(); }; int main() { some_concrete_worker w1; some_concrete_worker_2 w2; polymorhic_work(w1); //     polymorhic_work(w2); //  prepare_impl()  work_impl()  w1  w2 } 


рдЗрд╕ рддрд░рд╣ рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдХреА рдорджрдж рд╕реЗ, рдПрдХ рдбреЗрд╡рд▓рдкрд░ (рд╡рд╛рд╕реНрддреБрдХрд╛рд░) рдХреБрдЫ рдирд┐рд╢реНрдЪрд┐рдд рд╡рд░реНрдЧреЛрдВ рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдмрд╛рдХреА рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп рдХреБрдЫ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди CRTP рдХреНрд╖рдорддрд╛рдПрдВ рдпрд╣реА рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИрдВ ред

Mixin


MixIn рдПрдХ рдбрд┐рдЬрд╛рдЗрди рддрдХрдиреАрдХ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ (рдЗрдВрдЯрд░рдлрд╝реЗрд╕, рдореЙрдбреНрдпреВрд▓, рдЖрджрд┐) рдХреБрдЫ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдХрд┐рд╕реА рдЕрдиреНрдп рд╡рд░реНрдЧ рдореЗрдВ "рдорд┐рдХреНрд╕" рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдкрдиреЗ рдЖрдк рдкрд░, MixIn рд╡рд░реНрдЧ рдЖрдорддреМрд░ рдкрд░ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рддрдХрдиреАрдХ C ++ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдХреБрдЫ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рднрд╛рд╖рд╛ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕реНрддрд░ рдкрд░ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
C ++ рдореЗрдВ, MixIn рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдореВрд▓ рд╕рдорд░реНрдерди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдЗрд╕ рдореБрд╣рд╛рд╡рд░реЗ рдХреЛ CRTP рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, MixIn рд╡рд░реНрдЧ рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдпрд╛ рдХрд╛рдЙрдВрдЯрд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рдВрджрд░реНрднреЛрдВ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ "рдЕрдкрдиреЗ рдЖрдк" рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

 template<typename D> struct singleton{...}; class my_class : public singleton<my_class>{...}; 


рдпрд╣рд╛рдБ CRTP рдХреНрдпреЛрдВ рд╣реИ? рд╕рд┐рд░реНрдл рдПрдХ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЬреЛ рд╣рдореЗрдВ рдХреБрдЫ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ?

 struct singleton{...}; class my_class : singleton{...}; 


рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдорд┐рдХреНрд╕рдЗрди рдХреЗ рдЕрдВрджрд░ рд╣рдореЗрдВ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╡рд░реНрдЧ (рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ) рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рд╕реАрдЖрд░рдЯреАрдкреА рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИред рдФрд░ рдЕрдЧрд░ рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рджреВрд░ рдХреА рдХреМрдбрд╝реА рд▓рдЧрддрд╛ рд╣реИ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЬреЛ рдЖрдЬ рд╕рд┐рдВрдЧрд▓рдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ?), рддреЛ рдиреАрдЪреЗ рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдХреЗ рдХрд░реАрдм рджреЛ рдЙрджрд╛рд╣рд░рдг рдорд┐рд▓реЗрдВрдЧреЗред

Enable_shared_from_this

MixIn рд╕рдВрд░рдЪрдирд╛ (рдмреВрд╕реНрдЯ) std :: enable_sared_from_this рдЖрдкрдХреЛ рдПрдХ рдирдпрд╛ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╕рдореВрд╣ рдмрдирд╛рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

 struct bad { std::shared_ptr<bad> get() {return std::shared_ptr<bad>(this);} }; 


рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЧрдП рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдЭрд╛_рдкрд╛рд░реНрдЯ : :: () рдлрд╝рдВрдХреНрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╕рдореВрд╣ рдЦреЛрд▓рддрд╛ рд╣реИ, рдФрд░ рдЬрдм рд╢реЗрдпрд░реНрдб_рдкреНрдЯреНрд░ рдХреЛ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рдбрд┐рд▓реАрдЯ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕ рддрд░рд╣ рдХрд░рдирд╛ рд╕рд╣реА рд╣реИ:

 struct good : std::enable_shared_from_this<good> { std::shared_ptr<good> get() { return shared_from_this(); //    //  enable_shared_from_this } }; 


рдЗрд╕ рд╕рд╣рд╛рдпрдХ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 template<typename T> struct enable_shared { weak_ptr<T> t_; enable_shared() { t_ = weak_ptr<T>(static_cast<T*>(this)); } shared_ptr<T> shared_from_this() { return shared_ptr<T>(t_); } }; 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ CRTP рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдХреЛ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ "рджреЗрдЦрдиреЗ" рдФрд░ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдорд┐рд╢реНрд░рдг рд╕рдорд╛рд░реЛрд╣

MixIn рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХреБрдЫ рд╡рд░реНрдЧ рдХреЗ рдЕрдВрджрд░ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдХрднреА-рдХрднреА рдЗрд╕реЗ рдПрдХ рдореБрдлреНрдд рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рд╕рднреА рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП "! =" рдСрдкрд░реЗрдЯрд░ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП "==" рдСрдкрд░реЗрдЯрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

 template<typename D> struct non_equalable{}; template<typename D> bool operator != (const non_equalable<D>& lhs, const non_equalable<D>& rhs) { return !(static_cast<const D&>(lhs) == static_cast<const D&>(rhs)); } 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдСрдкрд░реЗрдЯрд░ рдХреЗ рдЕрдВрджрд░! = рд╣рдо рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ non_equalable рд╡реНрдпреБрддреНрдкрдиреНрди рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд "==" рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдЖрдк рдЗрд╕ MixIn рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 struct some_struct : non_equalable<some_struct> { some_struct(int w) : i_(w){} int i_; }; bool operator == (const some_struct& lhs, const some_struct& rhs) { return lhs.i_ == rhs.i_; } int main() { some_struct s1(3); some_struct s2(4); std::cout << (s1 != s2) << std::endl; } 


рдорд┐рдХреНрд╕ рдЕрдиреНрдп рддрд░реАрдХреЗ рдХреЗ рдЖрд╕рдкрд╛рд╕


рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рд╣рдо рдЦреЗрд▓ рдЕрдВрддрд░рд┐рдХреНрд╖ рдпрд╛рди рдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдЬрд╣рд╛рдЬ рдПрдХ рд╣реА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВрдЧреЗ, рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╢реЗрд╖ рдИрдВрдзрди рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рдФрд░ рд╡рд░реНрддрдорд╛рди рдЧрддрд┐ рдЬрд╣рд╛рдЬ рд╕реЗ рдЬрд╣рд╛рдЬ рддрдХ рднрд┐рдиреНрди рд╣реЛрдЧреАред рдкреИрдЯрд░реНрди рдЯреЗрдореНрдкрд▓реЗрдЯ рдкрджреНрдзрддрд┐ рдХрд╛ рдХреНрд▓рд╛рд╕рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдФрд░ рдпрд╣ рд╣реИ) рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

 class space_ship { public: // ... void move() { if(!fuel()) return; int current_speed = speed(); // further actions ... } virtual ~space_ship(){} private: virtual bool fuel() const = 0; virtual int speed() const = 0; }; class interceptor : public space_ship { public: // ... private: bool fuel() const { ... } int speed() const { ... } }; class other_ship : public space_ship { ... }; class other_ship_2 : public space_ship { ... }; // тАж 


рдЕрдм CRTP рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

 template<typename D> class space_ship { public: void move() { if(!static_cast<D*>(this)->fuel()) return; int current_speed = static_cast<D*>(this)->speed(); // ... } }; class interceptor : public space_ship<interceptor> { public: bool fuel() const; int speed() const; }; 


рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╣рдореЗрдВ рд╡рд░реНрдЪреБрдЕрд▓ рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓ рдЧрдпрд╛ рдФрд░ рдХреЛрдб рд╕реНрд╡рдпрдВ рдЫреЛрдЯрд╛ рд╣реЛ рдЧрдпрд╛ (рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдореЗрдВ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╡рд░реНрдЪреБрдЕрд▓ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ)ред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдорд┐рдХреНрд╕рдЗрди рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдЙрд▓реНрдЯрд╛ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдо рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧреЛрдВ рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд (рдЕрд▓рдЧ) рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ "рдорд┐рдХреНрд╕" рдХрд░рддреЗ рд╣реИрдВред

рдореИрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЗрд╕ рдбрд┐рдЬрд╛рдЗрди рддрдХрдиреАрдХ рдФрд░ рдорд┐рдХреНрд╕рд┐рди рдЖрд╣ рдкрд░ рдЕрдкрдирд╛ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рд╕реНрдкреЗрд╕рд╢рд┐рдк рдпрд╛ рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЗ рдХреГрддреНрд░рд┐рдо рдЙрджрд╛рд╣рд░рдг рд╕реЗ рд╢рд░реНрдорд┐рдВрджрд╛ рди рд╣реЛрдВред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ, рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЛ рдмрд╣реБрдд рд▓рдЪреАрд▓реЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рджреЛрд╣рд░рд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рд╕реЗ рдмрдЪрдиреЗ, рдЫреЛрдЯреА рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╕реНрдерд╛рдиреАрдп рдмрдирд╛рдиреЗ, рдФрд░ рдмрд╛рдж рдореЗрдВ рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рдЙрд╕ рдорд┐рд╢реНрд░рдг рдореЗрдВ "рдорд┐рд╢реНрд░рдг" рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрд╣ рдЙрди рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╣рдпреЛрдЧ рд╕реЗ рдЪрдордХрдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдХрдИ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ ( рдмреВрд╕реНрдЯ рджреЗрдЦреЗрдВ :: рд╕рдВрд▓рдпрди )ред

рдорд┐рдХреНрд╕рд┐рди рднрд┐рдиреНрдирддрд╛


рдореБрдЦреНрдп рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдореЗрдп ( FTSE ) рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ: "рдХрд┐рд╕реА рднреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рд╕реНрддрд░ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реНрддрд░реЛрдВ рдХреЛ рдкреЗрд╢ рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред" рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдЗрд╕реЗ CRTP MixIn рдкрд░ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЖрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдпреЛрдВ рдореЗрдВ рджреЗрдЦрд╛ рд╣реЛрдЧрд╛, "рд╕реНрдкрд╖реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕" рдФрд░ "рдорд┐рдХреНрд╕-рдЗрди рд╡рд┐рдкрд░реАрдд," рдореИрдВрдиреЗ рдПрдХ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдореЗрдВ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛, рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ "рдЪрд┐рдкрдХреЗ рд╣реБрдП" рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рдирд╣реАрдВ рд╣реИрдВред
рдЖрдк рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХреЛ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗ рдорд┐рддреНрд░ рдмрдирд╛рдХрд░ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдирд┐рдЬреА рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЛ рдХрдИ рдмреБрдирд┐рдпрд╛рджреА рдорд┐рдХреНрд╕рдЗрди рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдкрдХреЛ рд╕рднреА рдЖрдзрд╛рд░ рд╡рд░реНрдЧреЛрдВ рдХреЛ рдорд┐рддреНрд░ рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╡реНрдпрд╛рдкрдХ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП, рд╕рд╛рде рд╣реА рдХреБрдЫ рдкреБрд░рд╛рдиреЗ рд╕рдВрдХрд▓рдХреЛрдВ рдкрд░ рд╕рдВрдХрд▓рди рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рд╕реНрддрд░ рдХрд╛ рдПрдХ рдирдпрд╛ рд╕реНрддрд░ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдХрд╛рд░реНрдп рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред

 struct access { template<typename Impl> static void on_handle_connect(Impl* impl) {impl->handle_connect();} template<typename Impl> static void on_handle_response(Impl* impl) {impl->handle_response();} }; 


рдЕрдм рдЖрдзрд╛рд░ рд╡рд░реНрдЧреЛрдВ рд╕реЗ, рд╣рдо рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдордзреНрдпрд╡рд░реНрддреА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВред

 template<typename D> struct connection_handler { // ... void on_connection() { access::on_handle_connect(static_cast<D*>(this)); } }; template<typename D> struct response_handler { // ... void on_response() { access::on_handle_response(static_cast<D*>(this)); } }; 


рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдореЗрдВ, рджреЛрд╕реНрддреЛрдВ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХреНрд╕реЗрд╕ рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

 class combined_handler : public connection_handler<worker>, public response_handler<worker> { private: friend struct access; void handle_connect(){ std::cout << __PRETTY_FUNCTION__ << std::endl; } void handle_response(){ std::cout << __PRETTY_FUNCTION__ << std::endl; } }; 


рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдлрд╛рдпрджреЛрдВ рдореЗрдВ рдпрд╣ рддрдереНрдп рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд┐ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдЕрдкрдиреЗ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА "рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ" рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЙрдирд╕реЗ рдХреМрди рд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдп рдХрд╣реЗ рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдПрдХ рд╢рд┐рдерд┐рд▓ рдпреБрдЧреНрдорд┐рдд рдкреНрд░рдгрд╛рд▓реА рдЖрдорддреМрд░ рдкрд░ рдПрдХ рдордЬрдмреВрдд рдпреБрдЧреНрдорд┐рдд рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реА рд╣реЛрддреА рд╣реИ, рд╕рд╛рде рд╣реА рдпрд╣ рддрдереНрдп рднреА рд╣реИ рдХрд┐ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЙрд▓ рдПрдХ рдЬрдЧрд╣ (рдПрдХреНрд╕реЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ) рдПрдХрддреНрд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЙрдиреНрд╣реЗрдВ рдЕрдиреНрдп рд╡рд░реНрдЧ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдиреЗрддреНрд░рд╣реАрди рдЕрд▓рдЧ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдирдХрд╛рд░рд╛рддреНрдордХ рдкрдХреНрд╖, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдХреНрд╕рд░ рд╣реЛрддрд╛ рд╣реИ, рдбрд┐рдЬрд╛рдЗрди рдирд┐рд░реНрдгрдп рдХреА рдЬрдЯрд┐рд▓рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ рдкреВрдВрдЫ рдФрд░ рдЕрдпрд╛рд▓ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдпреЛрдЬрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЖрдЧреНрд░рд╣ рдирд╣реАрдВ рдХрд░рддрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЕрддрд┐рд╢реНрдпреЛрдХреНрддрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

Source: https://habr.com/ru/post/In210894/


All Articles