Kodu tekrar kullanma: Arkadaş olmayan yöntemlerle arkadaş yöntemleri

method sürümüne sahip method için kodu yeniden kullanmanın mümkün olduğunu mu merak ediyordum? Örneğin, aşağıda verilen örnekte, hem doSomething hem de initDoSomething yöntemleri aynı hesaplamaları yapar ve bu nedenle bunların uygulanması pratik olarak aynıdır. Kodu yeniden kullanmak için böyle bir şeyi yapmanın en iyi yolu hangisi olurdu?

template < typename T >
class CFoo;

template < typename T > CFoo doSomething( double );

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

Herhangi bir öneri memnuniyetle karşılanır ;-)

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
İnitDoSomething() CFoo üyelerine erişim sağlıyor mu? Eğer evet ise, doSomething() ile aynı şeyi nasıl yapabilir? Eğer değilse, neden bir üye?
katma yazar Luchian Grigore, kaynak
Benim düşünceme göre arkadaşlar ve şablonlardan kaçınılmalıdır. Sadece gerekirse bunları kullanın ve mantıklı bir anlam ifade ederler. Neden, tam olarak, elde etmeye mi çalışıyorsun?
katma yazar Ed Heal, kaynak
Fonksiyonel programlama ve nesne yönelimli programlama arasındaki farktan uzaklaşmanızı öneririm. Ayrıca static sözcüğünü de araştırıyorum.
katma yazar Ed Heal, kaynak
Whe her iki versiyona mı ihtiyacınız var? Bunun yerine initDoSomething statik bir işlev yapmanıza gerek yok mu?
katma yazar crazyjul, kaynak
Neyi başarmak istediğimi açıklayan orijinal yazımı güncelledim.
katma yazar Javier, kaynak

2 cevap

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
katma
" bir fonksiyonun bir sınıfın özel veri üyelerine erişmesi gerekiyorsa, onu bir arkadaş-fonksiyonundan ziyade sınıfın bir yöntemi yapmalısınız. " Neden?
katma yazar curiousguy, kaynak
Bana bir fabrika fonksiyonunu istediğin gibi geliyor ... Bu soru başlıyor initDoSomething 'in amacı nedir? Bir CFoo nesnesi oluşturmak için doSomething 'un çağırdığı basit bir "jeneratör" işlevi midir? Eğer öyleyse, static olması gerekir, çünkü yine de, yapıcının kendisinde yapmadığınız sürece, daha önce oluşturulmamış bir nesne üzerinde bir yöntemi çağıramazsınız. bu işaretçisi ... Ayrıca, istediğiniz şey buysa, initDoSomething doSomething 'a gerek yoktur./code> public olarak bildirildi.
katma yazar Jason, kaynak
Başarımı neyi başarmak istediğimi gösteren bir yazıyı güncelledim.
katma yazar Javier, kaynak

C ++ 'da kod kullanımının yeniden elde edilmesinin yolu, ortak kodu (muhtemelen parametrize edilmiş) paylaşılan işlevlere basitçe katıştırmaktır.

Durumunuzda, initDoSomething özel üyelere eriştiğini varsayalım (aksi halde, neden bir üye işlevidir?). Bu durumda, paylaştığınız fonksiyonun iki argüman alması ve initDoSomething 'ın özel üyeleri/üyeleri argüman olarak paylaşılan işleve iletmesidir.

0
katma
@curiousguy: Doğru, ama yazar yazarın oraya ait olduğunu düşünüyor mu? Mümkünse fonksiyon elemanlarını sadece gerekirse yapmalısınız.
katma yazar Frerich Raabe, kaynak
@curiousguy: Hayır; Paylaşılan kodun, argümanlarla gerekli değerleri (özel üye değişkenleri) alan işlevlere sokulması gerektiği kastediyorum. Bu şekilde, bu işlevler bir nesnenin tüm özel durumuna (bir arkadaş işlevinin yapabileceği) erişemez.
katma yazar Frerich Raabe, kaynak
" initDoSomething'in özel üyelere eriştiğini varsayalım (aksi halde, neden üye bir işlevdir?). " Neden bir üye? çünkü yazarın buraya ait olduğunu düşünüyor.
katma yazar curiousguy, kaynak
Yani bu işlevler üyeler yerine arkadaş olmalı? Mantıklı.
katma yazar curiousguy, kaynak
Cevabınızı gösteren bir örnek veriyor musunuz? Ayrıca, neyi başarmak istediğimi gösteren orijinal yazımı da güncelledim.
katma yazar Javier, kaynak