рд╢реБрдн рджрд┐рди, рдкрд╛рдардХред рдореИрдВ рдЖрдкрдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдЬреНрдЮрд╛рди рдХрд╛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреИрдЯрд░реНрдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдкрдиреЗ рдЬреНрдЮрд╛рди рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ - рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдХрд╛рд░рдЦрд╛рдирд╛, рдПрдХ рдЕрдиреНрдп рдирд╛рдо рднреА рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ - рдПрдХ рдЖрднрд╛рд╕реА рдирд┐рд░реНрдорд╛рддрд╛ред
рдпрд╣ рдХреИрд╕рд╛ рдкреИрдЯрд░реНрди рд╣реИ?
рдирд╛рдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд, рд╡рд┐рд╢рд┐рд╖реНрдЯ, рдХрд╛рд░рдЦрд╛рдирд╛ (рдпрд╛ рдХрд╛рд░рдЦрд╛рдирд╛) рд╣реИ рдЬреЛ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реИред рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдореИрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╢рдмреНрдж рд╡реНрдпрдХреНрдд рдХрд░реВрдВрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдХреА рддрд░рд╣, рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рдорд╛рди рдпрд╛ рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреА рд╣реИред рдФрд░ рдХрд╛рд░рдЦрд╛рдиреЗ, рдЬреЛ рдЙрддреНрдкрд╛рджрди рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдлрд░реНрдиреАрдЪрд░, рдирд┐рд░реНрдорд╛рдг рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдорд╛рд░реНрдЯрдлрд╝реЛрди рдХреЗ рд▓рд┐рдП рдШрдЯрдХ рднреАред рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдЕрдиреБрд░реВрдк, рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдлреИрдХреНрдЯреНрд░реА рдХреЗрд╡рд▓ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдПрдВ рдмрдирд╛ рд╕рдХрддреА рд╣реИ рдЬреЛ рдПрдХрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИрдВред C ++ рдореЗрдВ рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЗ рдореБрдЦреНрдп рд▓рд╛рдн рдПрдХрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╡рд░реНрдЧреЛрдВ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рд░рд▓реАрдХрд░рдг рд╣реИред рдЕрдХреНрд╕рд░, рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рди рдХреЗрд╡рд▓ рдХреБрдЫ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдмрд▓реНрдХрд┐ рдЙрдиреНрд╣реЗрдВ рднреА рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХреА рдлрд╛рдЗрд▓реЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд░рд╣рд╛ рд╣реИред рд╣рдореЗрдВ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдЕрдкрд▓реЛрдб рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдВрднрд╛рд╡рд┐рдд рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреА рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд▓реЛрдбрд░ рдХреЛ рдХреЙрд▓ рдХрд░рддреА рд╣реИред рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕реНрд╡рд┐рдЪреЗрд╕ рдЬреИрд╕реЗ рдирд┐рд░реНрдорд╛рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдпрджрд┐ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕ рд╡рд░реНрдЧ рдХреЛ рддрддреНрдХрд╛рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдФрд░ рдЕрдзрд┐рдХ рд╕рдВрднрд╡ рд╡рд┐рдХрд▓реНрдк рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рдЬрд┐рддрдирд╛ рдЕрдзрд┐рдХ рдпрд╣ рдбрд┐рдЬрд╝рд╛рдЗрди рдмрдврд╝рддрд╛ рд╣реИ, рдЬреЛ рдмрд╛рдж рдореЗрдВ рдПрдХ рдмрджрд╕реВрд░рдд рд░рд╛рдХреНрд╖рд╕ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред
рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдХрд╛рд░рдЦрд╛рдирд╛ рд╣рдореЗрдВ рдХреНрдпрд╛ рджреЗ рд╕рдХрддрд╛ рд╣реИ?
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рд╡рд┐рдзрд┐, рдЬреЛ рд╕реНрд╡рд┐рдЪ рдХреЛ рдХрдо рдХрд░ рджреЗрдЧреА / рдпрджрд┐ рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВред
рджреВрд╕рд░реЗ, рдХрд╛рд░рдЦрд╛рдиреЗ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗред рд╣рдо рд╣рдореЗрд╢рд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡рд░реНрдЧ рдЗрд╕рдХреЗ рд╕рд╛рде рдкрдВрдЬреАрдХреГрдд рд╣реИ, рдкрдВрдЬреАрдХреГрдд рдХрдХреНрд╖рд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛, рд╕рд╛рде рд╣реА рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рд╡рд░реНрдЧ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝рдиреЗ рдФрд░ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗред рдПрдХ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рд╕рдВрднрд╡ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЛ рд╕реАрдорд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдПрдВрдЧреЗред
рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдорд╛рдг
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЦрд╛рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХреЗ рдЬреЛ рдПрдХрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреА рд╣реИрдВред рд╣рдо рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдлреВ рдХрд╣рддреЗ рд╣реИрдВ, рдФрд░ рдХрд╛рд░рдЦрд╛рдиреЗ, рдХреНрд░рдорд╢рдГ, рдлреВрдлреНрдЯрд╡рд░реНрдХред рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реЗрдВред
lass FooFactory { public: FooFactory(); ~virtual FooFactory(); Foo * create(const std::string & id) const; };
рдФрд░ рдЗрд╕рд▓рд┐рдП, рдЕрдм рддрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдб рдХреА рдХреЗрд╡рд▓ рдПрдХ рджреЛ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рд▓рд┐рдЦреА рдЧрдИ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╣рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдирдХреЗ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ? рдЖрдЗрдП рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВред рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдХреНрд▓рд╛рд╕ рдХреЛ рдлрд╝реИрдХреНрдЯрд░реА рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдХрд┐рд╕реА рддрд░рд╣ рдХреЗ рдлрдВрдХреНрд╢рди рдХреА рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдПрдХ рдХрдХреНрд╖рд╛, рдПрдХ рд╡рд╕реНрддреБ рдирд╣реАрдВ, рдХреИрд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░реЗрдВ?
рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЖрдк рдХреНрд▓реЛрдирд┐рдВрдЧ рд░рдгрдиреАрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ, рдЗрд╕реЗ рдлрд╝реИрдХреНрдЯрд░реА рдореЗрдВ рдбрд╛рд▓реЗрдВ, рдФрд░ рдлрд╝реИрдХреНрдЯрд░реА рд╡рд┐рдзрд┐ рдмрдирд╛рддреЗ рд╕рдордп рдХреНрд▓реЛрди () рдкреНрд░рдХрд╛рд░ рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред рд╕рдЪ рдХрд╣реВрдВ рддреЛ, рд╡рд┐рдХрд▓реНрдк рдЦрд░рд╛рдм рд╣реИ, рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдлреВ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рдХреНрд▓реЛрди рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдФрд░ рд╕рднреА рдареЛрд╕ рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИред рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдПрдХ рд╡рд╕реНрддреБ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдкрд░, рд╣рдореЗрдВ рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА - рдЕрд░реНрдерд╛рдд, рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░реЗрдВред рдФрд░ рд╡рд╕реНрддреБрдПрдВ рдХрд╛рдлреА рднрд╛рд░реА рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рд╣рд╛рдВ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдзреБрдирд┐рдХ рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╕реНрдореГрддрд┐ / рдкреНрд░рджрд░реНрд╢рди рдХреА рд╕рдорд╕реНрдпрд╛ рдЗрддрдиреА рддреАрд╡реНрд░ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди C ++ рдРрд╕реА рднрд╛рд╖рд╛ рд╣реИ рдЬреЛ рдЙрдЪреНрдЪ-рд╕реНрддрд░ рдФрд░ рдирд┐рдореНрди-рд╕реНрддрд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рджреЛрдиреЛрдВ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдПрдХ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк, рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рдПрдХ рд╕реВрдЪрдХ рдХреЛ рдЙрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрд╛рд╕ рдХрд░реЗрдВ рдЬреЛ рдЖрдкрдХреЗ рдЗрдЪреНрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдХрдВрдХреНрд░реАрдЯ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рдФрд░ рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░реЗрдВред рдЖрдк рдореИрдХреНрд░реЛрдЬрд╝ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд╕реБрдВрджрд░ рдирд╣реАрдВ рд▓рдЧреЗрдЧрд╛, рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХрдИ рд▓реЛрдЧ рд╕реЛрдЪрддреЗ рд╣реИрдВ рдХрд┐ рд╕реА ++ рдореЗрдВ рдореИрдХреНрд░реЛрдЬрд╝ рдмреБрд░рд╛рдИ рд╣реИрдВред
рд▓реЗрдХрд┐рди рджреВрд╕рд░реА рдУрд░, C ++ рдореЗрдВ рдРрд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИрдВ рдЬреЛ рдЗрд╕ рдХрдард┐рди рдХрд╛рд░реНрдп рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред рдлреВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдиреНрдп рд╡рд╕реНрддреБрдУрдВ, рд╕рд╣рд╛рдпрдХ рд╡рд╛рд▓реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╣рдореЗрдВ рдЙрд╕ рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХрд╛ рдХрд╛рдо рд▓реЗрдЧрд╛ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдо рд▓реЛрдЧреЛрдВ рдореЗрдВ, рдРрд╕реЗ рд╡рд░реНрдЧреЛрдВ рдХреЛ рдирд┐рд░реНрдорд╛рддрд╛ рдпрд╛ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдЕрдореВрд░реНрдд рдирд┐рд░реНрдорд╛рддрд╛ рд╡рд░реНрдЧ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╡рд┐рдзрд┐ рд╣реЛрддреА рд╣реИ - рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛, рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рдлреВ рдХреА рд╡рд╕реНрддреБрдПрдВред рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреЗ рдареЛрд╕ рд╡рд░реНрдЧ рдмрдирд╛рдП рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдЕрдореВрд░реНрдд рдирд┐рд░реНрдорд╛рддрд╛ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдо рдХрд┐рд╕реА рднреА рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╕реНрдЯреЛрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдореИрдХреНрд░реЛрдЬрд╝ рдХреА рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рдПрдВрдЧреЗ, рдЬреЛ рдЖрдкрдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред
рдкреНрд░рдХрд╛рд░ рдлреВ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рд░ рд╡рд░реНрдЧ:
class abstractFooCreator { public: virtual fooCreator() {} virtual Foo * create() const = 0; };
рдФрд░ рдПрдХ рдЦрд╛рдХрд╛ рд╡рд░реНрдЧ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
template <class C> class fooCreator : public abstractFooCreator { public: virtual Foo * create() const { return new C(); } };
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рдзрд┐ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдВрдЪрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрдЯреЗрдирд░ рдЪреБрдиреЗрдВред рд╕реНрдкрд╖реНрдЯ рд╡рд┐рдХрд▓реНрдк std :: рдорд╛рдирдЪрд┐рддреНрд░ рд╣реЛрдЧрд╛ред
typedef std::map<std::string, abstractFooCreator*> FactoryMap; FactoryMap _factory; template <class C> void add(const std::string & id) { typename FactoryMap::iterator it = _factory.find(id); if (it == _factory.end()) _factory[id] = new fooCreator<C>(); }
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдкрд╣рд▓рд╛ рдХрд╛рд░реНрдпрд╢реАрд▓ рд╕рдВрд╕реНрдХрд░рдг рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдлреВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрдХреНрд╖рд╛рдПрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
рдЦреИрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдорд╛рд░реА рджреВрд╕рд░реА рд╕рдорд╕реНрдпрд╛, рдЕрд░реНрдерд╛рддреН рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг, рд▓рдЧрднрдЧ рд╣рд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдХреЗрд╡рд▓ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред
void Foo * create(const std::string & id) const { typename FactoryMap::iterator it = _factory.find(id); if (it != _factory.end()) return it->second->create(); return 0; }
рдкреВрд░реА рддрд╕реНрд╡реАрд░ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЛрдб рдЗрдХрдЯреНрдард╛ рдХрд░рддреЗ рд╣реИрдВред
рдЦреБрд▓рд╛ рд╣реИ class abstractFooCreator { public: virtual fooCreator() {} virtual Foo * create() const = 0; }; template <class C> class fooCreator : public abstractFooCreator { public: virtual Foo * create() const { return new C(); } }; lass FooFactory { protected: typedef std::map<std::string, abstractFooCreator*> FactoryMap; FactoryMap _factory; public: FooFactory(); ~virtual FooFactory(); template <class C> void add(const std::string & id) { typename FactoryMap::iterator it = _factory.find(id); if (it == _factory.end()) _factory[id] = new fooCreator<C>(); } Foo * create(const std::string & id) { typename FactoryMap::iterator it = _factory.find(id); if (it != _factory.end()) return it->second->create(); return 0; } };
рдЦреИрд░, рдЗрд╕ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдЙрджрд╛рд╣рд░рдгред рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдХрдХреНрд╖рд╛рдПрдВ рдЬреЛрдбрд╝рдирд╛:
FooFactory factory; factory.add<MyFoo>("MyFoo"); factory.add<MyFoo2>("MyFoo2"); factory.add<ImprovedFoo>("ImprovedFoo");
рдПрдХ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдирд╛:
Foo * p = factory.create("MyFoo2");
рдпрд╣ рдПрдХ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреА рдорджрдж рд╕реЗ рдЗрддрдирд╛ рд╕рд░рд▓ рд╣реИ, рдЖрдк рдЙрди рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред
рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдлреИрдХреНрдЯрд░реА рдмрдирд╛рдирд╛
рдЦреИрд░, рдЕрдм рдЖрдЗрдП, рдЗрд╕ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрдХ рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреИрдЯрд░реНрди рдмрдирд╛рддреЗ рд╣реИрдВред
рд╣рдорд╛рд░реЗ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЛ рд╣рдорд╛рд░реА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдмреЗрд╢рдХ, рдпрд╣ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХрд╛рдо рд╣реИ, рдЬреЛ рдпрд╛ рддреЛ рдПрдХ рдПрдиреБрдо, рдПрдХ std :: string, рдпрд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рджреВрд╕рд░рд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдмрдирд╛рдПрдВрдЧреЗ, рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рднреВрдорд┐рдХрд╛ рдлреВ рдХрдХреНрд╖рд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рднрд╛рдИ рдЧрдИ рдереАред
template <class Base, class IdType> class ObjectFactory { public: ObjectFactory() {} virtual ~ObjectFactory(); template <class C> void add(const IdType & id); Base * create() const; };
рдпрд╣ рд╣рдорд╛рд░рд╛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛рд░рдЦрд╛рдирд╛ рдХреИрд╕рд╛ рд╣реЛрдЧрд╛ред
рдЪрд▓реЛ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВред рдлреВ рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рд╣рдореЗрдВ рдПрдХ рд╕рд╛рд░ рд╡рд░реНрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдмреЗрд╕ рдмреЗрд╕ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ, рдФрд░ рдПрдХ рдареЛрд╕ рдирд┐рд░реНрдорд╛рддрд╛ рд╡рд░реНрдЧ рдЬреЛ рдЗрд╕ рд╕рд╛рд░ рд╡рд░реНрдЧ рдХреЛ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
template <class Base> class AbstractCreator { public: AbstractCreator() {} virtual ~AbstractCreator(){} virtual Base* create() const = 0; }; template <class C, class Base> class Creator : public AbstractCreator<Base> { public: Creator() { } virtual ~Creator() {} Base * create() const { return new C(); } };
рдЦреИрд░, рдЕрдм рдЖрдкрдХреЛ рд╣рдорд╛рд░реЗ рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдЗрди рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
template <class Base, class IdType> class ObjectFactory { protected: typedef AbstractCreator<Base> AbstractFactory; typedef std::map<IdType, AbstractFactory*> FactoryMap; FactoryMap _factory; public: ObjectFactory() {} virtual ~ObjectFactory(); template <class C> void add(const IdType & id) { registerClass(id, new Creator<C, Base>()); } protected: void registerClass(const IdType & id, AbstractFactory * p) { typename FactoryMap::iterator it = _factory.find(id); if (it == _factory.end()) _factory[id] = p; else delete p; } };
рдлреВ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдореЗрдВ рдХреНрдпрд╛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ? рдмреЗрд╢рдХ, рдпрд╣ рд░рдЬрд┐рд╕реНрдЯрд░рдХреНрд▓рд╛рд╕ рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдмреНрд╕рдЯреНрд░реИрдХреНрдЯ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд▓реЗрддреА рд╣реИ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ, рдХреНрд▓рд╛рд╕ рдХреА рдЙрди рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛ рд╕рдХрддреА рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдРрдб рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред
рдХрд╛рд░рдЦрд╛рдирд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝реЗрдВ
рдореИрдВ рдЕрдм рд╢реЗрд╖ рд╕рд░рд▓ рддрд░реАрдХреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛, рдЬреИрд╕реЗ рдХрд┐ рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рд╡рд░реНрдЧ рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛, рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рд╡рд┐рд▓реЛрдкрди - рдПрдХ рдкреВрд░реА рд╕реВрдЪреА рдЕрдВрдд рдореЗрдВ рдорд┐рд▓ рд╕рдХрддреА рд╣реИред рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЛ рдФрд░ рднреА рдЕрдзрд┐рдХ рд▓рдЪреАрд▓рд╛ рдмрдирд╛рдпрд╛ рдЬрд╛рдПред рджрд░рдЕрд╕рд▓, рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рд░рдЦреЗ рдЧрдП рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЖрдк рдХреБрдЫ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдорд╛рд░реЗ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрдЯрд┐рдВрдЧ рднреА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЕрдиреБрд░реЛрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ рдЬрдм рдЗрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рд╢реВрдиреНрдп рдкрд░ рд▓реМрдЯреЗрдВ рдпрд╛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХреЗрдВ? рдЕрдЧрд░ рдореИрдВ рдХрд╛рд░рдЦрд╛рдиреЗ рд╕реЗ рдПрдХ рдкрд╣рд▓реЗ рд╕реЗ рдкрдВрдЬреАрдХреГрдд рд╡рд╕реНрддреБ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдХреНрдпрд╛ рдХрд░реВрдВ? рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдФрд░ рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди - рд░рдгрдиреАрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдПрдХ рд░рд╛рдЬрдиреАрддрд┐рдЬреНрдЮ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдкреИрдЯрд░реНрди рдП рдЕрд▓реЗрдХреНрдЬреЗрдВрдбреНрд░реЗрд╕реНрдХреБ рдХреА рдкреБрд╕реНрддрдХ "рд╕реА ++ рдореЗрдВ рдЖрдзреБрдирд┐рдХ рдбрд┐рдЬрд╛рдЗрди" рдореЗрдВ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЬрд┐рди рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдореИрдВ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реВрдВ, рдлрд┐рд▓рд╣рд╛рд▓ рд╡реЗ рдХреЗрд╡рд▓ 2 рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИрдВред рддреНрд░реБрдЯрд┐ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЕрднрд╛рд╡, рдФрд░ рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрдирд╛ред рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рддреНрд░реБрдЯрд┐ рдХреЗ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдПрдХрдорд╛рддреНрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ, рд╣рдЯрд╛рдиреЗ рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реА рдиреАрддрд┐ рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:
template <class Base, class Type> class ObjectFactoryIgnoreErrorPolicy { public: Base * onCreateFailed(const Type & type) const { return 0; } void onRemoveFailed(const Type & type) {} void onDuplicateRegistered(const Type & type) {} };
рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд╕реНрд╡рдпрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдиреАрддрд┐ рд╡рд░реНрдЧ рдХреЛ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реБрдИ рдФрд░ рдЬрд┐рд╕реЗ рд╕рднреА рддрд░реАрдХреЛрдВ рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред IgnoreErrorPolicy рдХреЗ рд╕рд╛рде рд╕рдорд╛рдирддрд╛ рд╕реЗ, рдореИрдВ рдПрдХ рдиреАрддрд┐ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рднреА рджреВрдВрдЧрд╛ рдЬреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЙрджрд╛рд╣рд░рдг class ObjectFactoryException : public std::exception { std::string _msg; public: ObjectFactoryException(const std::string & msg) throw() : _msg(msg) {} virtual ~ObjectFactoryException() throw() {} virtual const char * what() const throw() { return _msg.c_str(); } }; template <class Base, class Type> class ObjectFactoryThrowExceptionErrorPolicy { public: std::string generateMessage(const char * msg, const Type & type) const { std::stringstream strm; strm << msg << ", requested type id : " << type; return strm.str(); } Base * onCreateFailed(const Type & type) const { throw ObjectFactoryException(generateMessage("ObjectFactory - can't create object (not registered)", type)); } void onRemoveFailed(const Type & type) { throw ObjectFactoryException(generateMessage("ObjectFactory - can't remove class (not registered)", type)); } void onDuplicateRegistered(const Type & type) { throw ObjectFactoryException(generateMessage("ObjectFactory - class already registered", type)); } };
рдЕрдм рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рд╣рдорд╛рд░реА рдиреАрддрд┐ рдХреЛ рдПрдореНрдмреЗрдб рдХрд░реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ - рдмрд╕ рдиреАрддрд┐ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ, рдпрд╛ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдиреАрддрд┐ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рджреЛрдиреЛрдВ рд╣реА рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдПрдХрдорд╛рддреНрд░ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХрд╛рд░рдЦрд╛рдирд╛ рд╡рд░реНрдЧ рд╕реЗ рдиреАрддрд┐ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреИрд╕реЗ рд╕реЗрдЯ рдХрд░реЗрдВред C ++ рдХреА рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдорджрдж рдХрд░реЗрдЧреА - рдЯреЗрдореНрдкрд▓реЗрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ред рдлреИрдХреНрдЯреНрд░реА рдХреНрд▓рд╛рд╕ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдХреНрд▓рд╛рд╕ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреНрд▓рд╛рд╕ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрддреНрддреАрд░реНрдг рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
template <class Base, class IdType, template <class, class> class ObjectFactoryErrorPolicy = ObjectFactoryIgnoreErrorPolicy > class ObjectFactory : public ObjectFactoryErrorPolicy<Base, IdType> { тАж
рддреАрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИ <рд╡рд░реНрдЧ, рд╡рд░реНрдЧ> рд╡рд░реНрдЧ ...
рд╕рд╛рде рд╣реА, рдЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдиреАрддрд┐ рддреБрд░рдВрдд рд╕реЗрдЯ рдХреА рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ рдиреАрддрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рдЯрд╛рдЗрдкрдлреЗрдб рдХреЗ рд╕рд╛рде, рдЖрдкрдХреЛ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдиреАрддрд┐ рдХреЗ рд╕рд╛рде рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
typedef ObjectFactory<Foo, FooType, ObjectFactoryThrowExceptionPolicy> FooFactory;
рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рдЕрдХреНрд╕рд░ рдиреАрддрд┐ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИред рдЖрдк рдЖрдЧреЗ рднреА рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдиреАрддрд┐ рдХреЛ рдЧрддрд┐рд╢реАрд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде, рд▓реЗрдХрд┐рди рдлрд┐рд▓рд╣рд╛рд▓ рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЕрднреА рддрдХ рдореЗрд░реЗ рдЫреЛрдЯреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЗрд╕ рддрдВрддреНрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рдереАред рджрд░рдЕрд╕рд▓, рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдиреАрддрд┐ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдХреА рдкрджреНрдзрддрд┐ рдХреЛ рдЪреБрдирд╛, рдФрд░ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ред
рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ
рдЦреИрд░, рдЕрдм рд╕реНрдЯреЙрдХ рд▓реЗрдиреЗ рдФрд░ рдореЗрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдкреИрдЯрд░реНрди рдХреА рдкреВрд░реА рд╕реВрдЪреА рдкреЗрд╢ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред
рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ #include <map> #include <string> #include <memory> #include <sstream> namespace grs { /* , */ template <class Base> class AbstractCreator { public: AbstractCreator() { } virtual ~AbstractCreator() { } virtual Base* create() const = 0; private: AbstractCreator(const AbstractCreator&); AbstractCreator& operator = (const AbstractCreator&); }; template <class C, class Base> class Creator : public AbstractCreator<Base> { public: Creator() { } virtual ~Creator() { } Base * create() const { return new C(); } }; /* */ class ObjectFactoryException : public std::exception { std::string _msg; public: ObjectFactoryException(const std::string & msg) throw() : _msg(msg) {} virtual ~ObjectFactoryException() throw() {} virtual const char * what() const throw() { return _msg.c_str(); } }; template <class Base, class Type> class ObjectFactoryIgnoreErrorPolicy { public: Base * onCreateFailed(const Type & type) const { return 0; } void onRemoveFailed(const Type & type) { } void onDuplicateRegistered(const Type & type) { } }; template <class Base, class Type> class ObjectFactoryThrowExceptionErrorPolicy { public: std::string generateMessage(const char * msg, const Type & type) const { std::stringstream strm; strm << msg << ", requested type id : " << type; return strm.str(); } Base * onCreateFailed(const Type & type) const { throw ObjectFactoryException(generateMessage("ObjectFactory - can't create object (not registered)", type)); } void onRemoveFailed(const Type & type) { throw ObjectFactoryException(generateMessage("ObjectFactory - can't remove class (not registered)", type)); } void onDuplicateRegistered(const Type & type) { throw ObjectFactoryException(generateMessage("ObjectFactory - class already registered", type)); } }; /* */ template <class Base, class IdType = int, template <class, class> class ObjectFactoryErrorPolicy = ObjectFactoryIgnoreErrorPolicy > class ObjectFactory : public ObjectFactoryErrorPolicy<Base, IdType> { protected: typedef AbstractCreator<Base> AbstractFactory; typedef std::map<IdType, AbstractFactory*> FactoryMap; public: ObjectFactory() { } virtual ~ObjectFactory() { for (typename FactoryMap::iterator it = _map.begin(), endIt = _map.end(); it != endIt; ++it) delete it->second; } Base * create(const IdType & id) const { typename FactoryMap::const_iterator it = _map.find(id); if (it != _map.end()) return it->second->create(); return onCreateFailed(id); } template <class C> void add(const IdType & id) { registerClass(id, new Creator<C, Base>); } void remove(const IdType & id) { typename FactoryMap::iterator it = _map.find(id); if (it != _map.end()) { delete it->second; _map.erase(it); } else onRemoveFailed(id); } bool isRegistered(const IdType & id) const { return _map.find(id) != _map.end(); } size_t size() const { return _map.size(); } protected: void registerClass(const IdType & id, AbstractFactory * pAbstractFactory) { std::auto_ptr<AbstractFactory> ptr(pAbstractFactory); typename FactoryMap::iterator it = _map.find(id); if (it == _map.end()) _map[id] = ptr.release(); else onDuplicateRegistered(id); } private: ObjectFactory(const ObjectFactory&); ObjectFactory& operator = (const ObjectFactory&); FactoryMap _map; }; } // end of grs namespace
рдПрдХ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдЙрджрд╛рд╣рд░рдг #include "ObjectFactory.h" #include <iostream> enum Type { fooType, barType, maskedType, unknownType, firstType = fooType, lastType = maskedType, }; std::ostream & operator << (std::ostream & strm, const Type & type) { const char * names[] = {"foo", "bar", "masked"}; if (type < firstType || type > lastType) return strm << "unknown type(" << int(type) << ")"; return strm << names[type]; }; class Base { public: virtual ~Base() {} virtual Type type() const = 0; }; class Foo : public Base { public: virtual Type type() const { return fooType; } }; class Bar : public Foo { public: virtual Type type() const { return barType; } }; class MaskedFoo : public Foo { public: virtual Type type() const { return barType; } }; typedef grs::ObjectFactory<Base, Type> TypeFactory; void checkType(TypeFactory & factory, Type type) { std::auto_ptr<Base> p; p.reset(factory.create(type)); std::cout << "Object with type : " << type; if (p.get()) { if (type == p->type()) std::cout << " - successfully created\n"; else std::cout << " - created, but type mismatch\n"; } else std::cout << " - create failed\n"; } int main() { TypeFactory factory; factory.add<Foo>(fooType); factory.add<Bar>(barType); factory.add<MaskedFoo>(maskedType); checkType(factory, fooType); checkType(factory, barType); checkType(factory, maskedType); checkType(factory, unknownType); return 0; }
рдЖрдк рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде
рдмрд┐рдЯрдмрдХреЗрдЯ рдХреЗ рд╕рд╛рде рдПрдХ рдкреИрдЯрд░реНрди рднреА рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╡рд╣рд╛рдВ рдХрдИ рдЕрдиреНрдп рдЙрдкрдпреЛрдЧреА рдХрдХреНрд╖рд╛рдПрдВ рд╣реИрдВред
рд╡рд╣ рд╕рдм рд╣реИред рдЕрдЪреНрдЫрд╛ рдФрд░ рд░рдЪрдирд╛рддреНрдордХ рдХреЛрдбрд┐рдВрдЧ!
рд╕рдВрджрд░реНрдн
рдпрджрд┐ рдЖрдк рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рдЗрди рдкреБрд╕реНрддрдХреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдПред рдЕрд▓реЗрдХреНрдЬреЗрдВрдбреНрд░реЗрд╕реНрдХреБ рдХреА рдкреБрд╕реНрддрдХ рдореЗрдВ, C ++ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ, рдЬрдм рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЕрд╡рдЧрдд рдХрд░рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ 4 рдЧрд┐рд░реЛрд╣реЛрдВ рдХреА рдкреБрд╕реНрддрдХ рдореЗрдВ, рдЖрдк рдХрдИ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдкреИрдЯрд░реНрди рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред