2017-03-29 18 views
6

Daha önce C++'daki Operatörlerin bir üye fonksiyonlarının yanı sıra bir sınıfın arkadaş fonksiyonları olarak aşırı yüklenmesini öğrendim. Her ne kadar, her iki tekniği kullanarak C++ 'da operatörlerin nasıl yükleneceğini biliyorum. Ama yine de şaşkınım ** hangisi daha iyi **? Bir kullanıcı işlevini veya bir arkadaş işlevini işleçleri aşırı yüklemek için, hangisini kullanmalıyım ve neden kullanmalıyım? Lütfen bana yol göster! Cevabınız büyük ölçüde takdir edilecektir. Cevaplarınız için sevinirim ve müteşekkirim.Arkadaşıma üye fonksiyonlar ve işlevsellik Aşırı yüklenme C++

+2

Küresel arkadaşlık dışı işlevler ne durumda? Her iki durumda da, üye olmaktan her zaman küresel olmayı tercih ederim. – DeiDei

+0

global arkadaşlık dışı işlevler? Aşırı yüklenmiş bir operatörün sadece arkadaş veya üye işlevi olabileceğini düşündüm. Ama teşekkürler ! Ben de onu araştıracağım. –

+0

'friend' yalnızca sınıfa ait 'private' ve' protected' üyelerine işlev erişimi vermek için gereklidir. Aksi takdirde bu gerekli değilse o zaman 'arkadaşa' gerekli değildir. – DeiDei

cevap

0

Muhtemelen bunun için sabit bir kural yoktur, bu yüzden sadece fikrimi verdim: mümkünse, operatör aşırı yüklenmesi için üye işlevini kullanın. Bunun temel nedeni, operatörlerin, sınıfın ayrılmaz bir parçası olduğunu ve sınıfın mantığının daha yerel olduğunu görmem.

Operatör aşırı yüklemesi için ücretsiz işlevlerin tercih edilmesinin nedeni, sınıfı olabildiğince zayıf tutmaktır (yalnızca gerektiğinde arkadaş kullan).

Bazı durumlarda, operatörler üye olamaz, bu nedenle bu durumda tartışma olmaz. Esas olarak üye işlevleri, her zaman mümkün olmayan birinci parametre olarak sınıf örneğine sahiptir (örneğin, i/o için operatör < <).

2

Üye işlevleri ve arkadaları, yalnızca bir tanesini seçmeniz gereken iki karşıt değildir. Her ikisi de, örneğin birini uygulamak ve diğerini çağırmak suretiyle kodları çoğaltmaktan kaçınmak için kullanılabilir.

struct A 
{ 
    A operator+=(A const & second); 
}; 

A operator+(A const &first, A const &second) 
{ 
    A temp(first); 
    temp += second; 
    return temp; 
} 

Ama

için seçmek istiyorsanız durumunda o üye ya da olmamak gerekiyorsa işlevi, burada benim takip bir kural biri: üye olmayan bir işlevi uygulamak için ( friend veya değil) Beklediğimiz simetriye saygı duymak için bir ikili operatörüne sahibim. Örnek: A ile ve int'u A'a ( int numaralı bir kurucu ile) dönüştürme olanağı, eğer bir üye fonksiyonum varsa, sonuç ne olacak.

A a1, a2; 
a1 + a2; // OK 
a1 + 42; // OK 
42 + a2; // KO 

Ücretsiz bir işlevle sonuç ortaya çıkar. Bu olasılığı kullanmak

A a1, a2; 
a1 + a2; // Ok 
a1 + 42; // Ok 
42 + a2; // Ok 

bir beton C++ sınıfı std::string olup.

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string s {"World"}; 
    // Works with absolutely no problem. 
    std::string chaine = "Hello " + s; 
    std::cout << chaine << std::endl; 
} 

size yardım etmeye SO üzerinde good link olduğunu belirtmek isterim.

+0

Teşekkürler Çok Efendim :-) Çok Yardım Etti :-) –

3

Seçim "üye veya arkadaş" değil, "üye veya üye olmayan" değildir.
(Arkadaşlık sıkça kullanılır ve genellikle okullarda çok erken öğretilir.)

Bunun nedeni, her zaman serbest bir işlevin çağırabileceği bir genel üye işlevi ekleyebilmenizdir. Örneğin

:

class A 
{ 
public: 
    explicit A(int y) : x(y) {} 
    A plus(const A& y) const { return A{x + y.x}; } 
private: 
    int x; 
}; 

A operator+(const A& lhs, const A& rhs) { return lhs.plus(rhs); } 

nasıl seçileceği gelince: operatörü, sol taraftaki işlenen olarak sınıfının bir örneğini almaz ise, o aksi takdirde var, özgür bir işlevi olmalı Neredeyse kişisel bir zevk meselesi (veya yalnız değilseniz kodlama standartları).

Örnek:

: karşılık gelen bir değişen yapısıyla operatörünün operatörleri (gibi + ve +=), bir üye ve bir dışı elemanı gibi diğer olarak değişen yapısıyla operatörü oluşturmak için yaygın için

// Can't be a member because the int is on the left. 
A operator+ (int x, const A& a) { return A{x} + a; } 

class B 
{ 
public: 
    explicit B(int y) : x(y) {} 
    B& operator+= (const B& y) { x += y.x; return *this; } 
private: 
    int x; 
}; 

B operator+(B lhs, const B& rhs) { return lhs += rhs; } 

ama tabii ki de bu yazım olabilir:

class C 
{ 
public: 
    explicit C(int y) : x(y) {} 
    C& add(const C& y) { x += y.x; return *this; } 
private: 
    int x; 
}; 

C& operator+=(C& lhs, const C& rhs) { return lhs.add(rhs); } 
C operator+(C lhs, const C& rhs) { return lhs += rhs; } 
+0

Çok Teşekkürler :-) Büyük Bilgi Efendim! –

1

Tatsızlıktan uzak değil, bazı kullanım durumları açıkça iki yoldan birini gerektirir.

Operatör yalnızca argüman olarak aldığınızda, yalnızca üye olduğunuz sınıfın üyeleri, üye işlevini kullanmak için kapsayıcı oy kullanır. Örnek: İki nesne eklenmesi: Yazdığınız sınıfın üyesi operatörünün ikinci argümanı karşısında ise

class A { 
    ... 
    A operator + (const class A& other); // naturally a member function 
    ... 
}; 

, yalnızca At arkadaş fonksiyonunu

std::outstream& operator << (std::outstream& out, const class A& a); 

class A { 
    ... 
    friend std::outstream& operator << (std::outstream& out, const class A& a); // must be friend here 
}; 

kullanabilirsiniz std::outstream'un bir üyesi olabilir, ancak std::outstream sınıfı standart C++ kütüphanesinde oluşturulduğunda A sınıfı mevcut değildi ...

+0

Teşekkürler Efendim :-) Sizden yeni bir şey öğrendim :-) –

İlgili konular