Kodni qayta ishlatish: do'stsiz usullar bilan do'st usullari

do'st versiyasiga ega usullari uchun kodni qayta ishlatish mumkinmi deb hayron bo'ldim. Misol uchun, quyida keltirilgan misolda doSomething va initDoSomething usullari bir xil hisob-kitoblarni bajaradi va shuning uchun ularni amalga oshirish deyarli bir xil. Kodni qayta ishlatish uchun bunday narsalarni qilishning eng yaxshi yo'li qanday bo'ladi?

template < typename T >
class CFoo;

template < typename T > CFoo doSomething( double );

template < typename T >
class CFoo{
    public:
        ...
        friend CFoo doSomething< >( double );
        CFoo initDoSomething( double );
};

Har qanday taklifni qabul qilish ;-)

What I would like to achieve is something like: myFooObject1 = doSomething(3.0); without needing to necessarily initialize an object or also: myFooObject1.doSomething(3.0);

1
CFoo-dan initDoSomething() a'zolaridan foydalanish mumkinmi? Ha bo'lsa, qanday qilib xuddi shu narsani qilish mumkin? Agar bo'lmasa, nima uchun u a'zo?
qo'shib qo'ydi muallif Luchian Grigore, manba
O'zimning kamtarona fikrimcha do'stlarim va shablonlardan qochishim kerak. Zarur bo'lganda ulardan foydalaning va ular mantiqiy ma'noga ega bo'ladilar. Nima uchun, aniq qilib, erishishga intilyapsizmi?
qo'shib qo'ydi muallif Ed Heal, manba
Funktsional dasturlash va ob'ektga asoslangan dasturlash orasidagi farqni ketkazishni taklif qilaman, shuningdek static so'zini toping.
qo'shib qo'ydi muallif Ed Heal, manba
Har ikkala variant ham kerakmi? Buning o'rniga initDoSomething-ni statik funktsiyani bajarishingiz kerak emasmi?
qo'shib qo'ydi muallif crazyjul, manba
Men o'zimning asl nashrni yangilab oldim.
qo'shib qo'ydi muallif Javier, manba

2 javoblar

Generally speaking, if a function needs to access the private data-members of a class, you should make it a method of the class rather than a friend-function. There are specific instances where you may want to have a friend function, such as with and overloaded version of operator>>, etc., in order to create a common interface between your objects and other standard C++ interfaces such as streams. Another common use of a stand-alone friend function would be for creating a single function interface that will be parameterized in some way, but you want to keep the interface for that function the same (i.e., a single template-function may take multiple different class types, but you want to call that function the same way with any instantiated version). In general though, making functions as friends of a class just so they can access the private data members of a class breaks the entire idea of data encapsulation that classes create for their private data members in the first place.

In your case, you haven't explicitly explained why doSomething has to be a friend and not a method ... as it stands right now, with the function declaration, there doesn't seem to be any reason why it can't be a public method of CFoo. Secondly, if you are trying to initialize a global-state for your doSomething function, you will want to make initDoSomething a static function of the class rather than a method, so that every version of CFoo is initialized for a call to doSomething rather than just a single instance of CFoo. As it stands right now, you would have to initialize every instance of CFoo before it can be used with doSomething. Semantically that doesn't make sense since doSomething creates a CFoo instance before you can call initDoSomething on that instance to initialize it for a call to doSomething.

1
qo'shib qo'ydi
" Agar funktsiya sinfning maxsus ma'lumotlariga kirishi kerak bo'lsa, uni do'st funktsiyasi emas, balki sinfning usulini yaratish kerak. " Nima uchun?
qo'shib qo'ydi muallif curiousguy, manba
Menga asosan siz fabrika funktsiyasini istaganingiz kabi aytiladi ... Bu savolga initDoSomething nima maqsadda keladi? CFoo obyektini yaratish uchun faqat doSomething chaqiradigan "generator" funktsiyasi bormi? Agar shunday bo'lsa, uni static bo'lishi kerak, chunki bundan keyin siz konstruktorda o'zi qilmagan holda (masalan, this pointer) ... Bundan tashqari, siz istagan narsangiz bo'lsa, u holda initDoSomething funktsiyasi uchun doSomething /code> kodi public deb e'lon qilinadi.
qo'shib qo'ydi muallif Jason, manba
Nimani olishni istaganimni ko'rsatadigan asl nusxasini yangiladim.
qo'shib qo'ydi muallif Javier, manba

C ++ da kodni qayta ishlashga erishish uchun oddiy usulda umumiy kodlarni (ehtimol parametrlangan) birgalikdagi funktsiyalarga solish.

Sizning holatingizda initDoSomething shaxsiy a'zolar uchun kiradi (aks holda, nima uchun bu funktsiyadan foydalaniladi?). Shunday qilib, sizning sheriklaringiz bilan birgalikdagi funktsiyangiz ikki argumentni oladi va initDoSomething maxsus a'zolar (lar) ni argumentlar sifatida umumiy funktsiyaga o'tkazadi.

0
qo'shib qo'ydi
@curiousguy: To'g'ri, lekin u nima uchun muallifi u yerga tegishli deb o'ylaydi? Agar imkon bo'lsa, kerak bo'lganda funktsional a'zolarni amalga oshiring.
qo'shib qo'ydi muallif Frerich Raabe, manba
@curiousguy: Yo'q; Demak, birgalikda kodni kerakli qiymatlarni (masalan, xususiy a'zolarning o'zgaruvchilari) argumentlar orqali amalga oshiradigan funktsiyalarga qo'yish kerak. Shu tarzda, bu funktsiyalar ob'ektni all maxsus holatiga (do'st funktsiyasi bajarishi mumkin) kira olmaydi.
qo'shib qo'ydi muallif Frerich Raabe, manba
" Menimcha, initDoSomething shaxsiy a'zolar uchun kiradi (aks holda, nima uchun u a'zo funktsiyasi?) " Nima uchun a'zolar? chunki muallif bu yerga tegishli deb o'ylaydi.
qo'shib qo'ydi muallif curiousguy, manba
Sizning vazifangiz a'zolardan ko'ra do'st bo'lish kerakmi? Manoga ega.
qo'shib qo'ydi muallif curiousguy, manba
Javobingizning misolini keltirib chiqarasizmi? Bundan tashqari men o'zimning asl nashrni yangilagan narsamni qanday yangilaganimni namoyish qildim.
qo'shib qo'ydi muallif Javier, manba