const önce parametre vs işlev adından sonra const c ++


89

Böyle bir şeyin arasındaki fark nedir

friend Circle copy(const Circle &);

ve bunun gibi bir şey

friend Circle copy(Circle&) const;

Bu işlevin derleyiciye çağrıldığı nesneyi değiştirmeye çalışmayacağını söylemek için kullanıldıktan sonra const olduğunu biliyorum, peki ya diğeri?


6
parametreyi değiştirmeyeceğin
Çad

Yanıtlar:


199

İlk biçim Circle, copy()işlevin parametresi olan referansa bağlı nesnenin (durumunun) bu referansla değiştirilmeyeceği copy()anlamına gelir. Referans bir referanstır const, bu nedenle Circlekendileri olarak nitelendirilmemiş üye işlevlerini bu referans aracılığıyla çağırmak mümkün olmayacaktır const.

İkinci form, diğer taraftan, yasadışı: Sadece üye fonksiyonları olabilir constulaşım kolaylığı (ne bildiriyorlar küresel varken,friend fonksiyonu).

Bir constüye işlevi nitelendirdiğinde, niteleme örtük thisargümanı ifade eder . Başka bir deyişle, bu işlevin çağrıldığı nesnenin durumunu (örtük thisişaretçi tarafından gösterilen nesne) değiştirmesine izin verilmeyecektir - istisnamutable nesneler , ama bu başka bir hikaye.

Kodla söylemek için:

struct X
{
    void foo() const // <== The implicit "this" pointer is const-qualified!
    {
        _x = 42; // ERROR! The "this" pointer is implicitly const
        _y = 42; // OK (_y is mutable)
    }

    void bar(X& obj) const // <== The implicit "this" pointer is const-qualified!
    {
        obj._x = 42; // OK! obj is a reference to non-const
        _x = 42; // ERROR! The "this" pointer is implicitly const
    }

    void bar(X const& obj) // <== The implicit "this" pointer is NOT const-qualified!
    {
        obj._x = 42; // ERROR! obj is a reference to const
        obj._y = 42; // OK! obj is a reference to const, but _y is mutable
        _x = 42; // OK! The "this" pointer is implicitly non-const
    }

    int _x;
    mutable int _y;
};

12
Helluva cevap! Teşekkür ederim!
SexyBeast

1
Yani, ikinci durum için, bir varsa constnesne objsınıfının Xve dediğim bar()gibi obj.bar(obj)neden olur ve için ne gerekiyor? Arayan kişi bildirildiği için obj._x = 42başarısız olmamalı mı ? objconst
SexyBeast

1
İkinci bar function ( void bar(X const& obj) {...}) 'yı böyle yaptığın durumda ne olacak ? void bar(const X& obj) {...}, constanahtar kelimeyi bu konuma taşımak herhangi bir şeyi değiştirir mi? Varsa bu örneği de ekleyebilir misiniz lütfen?
Gabriel Staples

1
@GabrielStaples Onlar aynı; constsolunda olana ya da solunda hiçbir şey olmaması durumunda sağındakine uygulanır. Sizin durumunuzda, her iki sürüm için de constuygulandığını göreceksiniz X.
Andreas Flöjt

69

C ++ sınıfı yöntemlerin thistüm açık olanlardan önce gelen örtük bir parametresi vardır. Yani bir sınıf içinde şu şekilde bildirilen bir işlev:

class C {
  void f(int x);

Gerçekten şöyle göründüğünü hayal edebilirsiniz:

  void f(C* this, int x);

Şimdi, bu şekilde beyan ederseniz:

  void f(int x) const;

Sanki şunu yazmışsın:

  void f(const C* this, int x);

Bu arka, bir consthale thissınıf Çeşidi const nesneler üzerinde yöntemini çağırmak anlamı, parametre İnşaat, ve bu yöntem (en azından normal kanalı aracılığıyla) çağrıldığı nesne değiştirilmeden.


2
Mükemmel bir şekilde doğru, ancak soruya cevap vermiyor, bu aslında bir sınıf yöntemine değil, bir arkadaş işlevine atıfta bulunuyor.
mah

5
Evet, friendkısmı görmezden gelmeyi seçtim çünkü bunun OP'nin gerçek sorusuyla (ya da tüm sorunlar ortaya çıktığında asıl sorunun ne olacağı) aslında ilgisiz olduğunu düşünüyorum. Öyle olsun.
John Zwinck

const olmayan işlevler yalnızca const olmayan nesneler tarafından çağrılabilirken, const yöntemini const nesnelerinde veya const olmayan nesnelerde çağırabildiğiniz için "yöntemi sınıf türündeki const nesnelerinde çağırabilirsiniz" demenin biraz yanıltıcı olduğunu düşünüyorum. aksi halde bu benim favori cevabım
csguy

8
Circle copy(Circle&) const;

işlevi constkendisi yapar . Bu yalnızca bir sınıfın / yapının üye işlevleri için kullanılabilir.

Üye işlevi yapmak constşu anlama gelir:

  • o olamaz herhangi const olmayan üye işlevleri çağırmak
  • o olamaz herhangi bir üye değişkenleri değiştirmek.
  • bir constnesne tarafından çağrılabilir ( constnesneler yalnızca constişlevleri çağırabilir ). Const olmayan nesneler de bir constişlevi çağırabilir .
  • Bu gerekir sınıfın 'üyesi fonksiyonu Çember '.

Şimdi bir sonrakini düşünün:

Circle copy(const Circle &);

ancak bu, iletilen parametrenin işlev içinde değiştirilemeyeceği anlamına gelir. Sınıfın bir üye işlevi olabilir veya olmayabilir.

NOT: Bir işlevi const, aynı işlevin sabit olmayan bir sürümüne sahip olacak şekilde aşırı yüklemek mümkündür .


8

ŞUNLA İLGİLİ TÜM KARIŞMAYI TEMİZLEYELİM const


constgelen sabit ortalama bir şey değiştirilebilir ama okunamıyor.

  1. Değişkenimizi constanahtar kelime ile nitelendirirsek , daha sonra değiştiremeyiz.
    Örneğin, const değişkeni bildirildiğinde başlatılmalıdır.
    constint var =25;
    var =50; // gives error

  2. Biz bizim işaretçi değişkeni nitelemek eğer sonra o zaman olamaz işaretçi kendisi değiştirmek ancak ibrenin içeriğidir değiştirilebilir . örneğin // amaconst *

    int *const ptr = new int;
    ptr = new int; //gives error

    *ptr=5445; //allowed

  3. Biz bizim işaretçi değişkeni nitelemek eğer daha önce o zaman olabilir kendisi işaretçi değiştirmek ancak ibrenin içeriğidir değiştirilemez . örneğin // amaconst *

    intconst* ptr = new int(85);
    //or
    constint * ptr = new int(85);
    ptr = new int; // allowed

    *ptr=5445; // gives error

  4. işaretçi ve içerik hem sabit
    örn.
    intconst*constptr = new int(85);
    //or
    constint *constptr = new int(85);
    ptr = new int; // not allowed
    *ptr=5445; // not allowed


  1. Circle copy(const Circle &);
    Burada const Circle, Circle değerinin sadece okunabilir olduğu anlamına gelir, eğer Circle'ın değerini fonksiyon içinde değiştirmeye çalışırsak, o zaman hata verir.
  2. friend Circle copy(Circle&) const;
    Bu tür işlev, üye olmayan değişken için değildir. Sınıf veya yapı için kullanılır. Burada tüm işlev const anahtar sözcüğü ile nitelendirilir, yani nesne üye değişkenini değiştiremeyiz . Örneğin
    class A{ public :
              int  var;
              void fun1()
                    { var = 50; // allowed
                    } 
              void fun2()const
                       { var=50; //not allowed
                       }
           }; 

4

Biri parametreye, diğeri işleve atıfta bulunur.

Circle copy(const Circle &);

Bu, iletilen parametrenin işlev içinde değiştirilemeyeceği anlamına gelir

Circle copy(Circle&) const;

constNitelikli fonksiyon üye işlevleri ve sen kendini nesne veri üyelerini değiştiremezsiniz aracı kullanılır. Gönderdiğiniz örnek anlamsızdı.

Sağdan sola oku

İlk işlevi olarak yeniden yazarsak Circle copy(Circle const&);, ki bu aynı anlama gelir, sağdan sola okumanın faydalı olacağı anlaşılır. bir nesneye referans copyalan ve constreferans olarak bir Circlenesneyi döndüren bir işlevdir Circle.


0

friend Circle copy(const Circle &);// fonksiyonun sabit parametresini ifade eder. parametre tarafından saklanan değeri değiştiremezsiniz.

Örneğinizde arkadaşınızı kaldırmanız gerekiyor Circle copy (Circle &) const; // Sabit üye işlevi olarak adlandırılan bu poniter değeri değiştirilemez


0
friend Circle copy(const Circle &);

Fonksiyon çağrıları sırasında parametrenin değeri değişmeyecektir.

friend Circle copy(const Circle &)const ; 

İşlev, sınıf üyelerinin hiçbir değerini değiştirmeyen bir erişimcidir. Genel olarak, işlev türleri vardır: erişimciler ve mutatörler. Erişimci: nesnesinin durumunu inceler ancak değiştirmez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.