'::' yerine 'konulur. 'C ++' da belirsizlikler yaratıyor mu?


95

C ++ uygulamasında, ::bir ad alanındaki veya sınıftaki sınıflara, işlevlere ve değişkenlere erişmek için kullanılır.

Bu durumlarda .yerine kullanılan dil belirtimi ::bir nesnenin örnek değişkenlerine / yöntemlerine erişimde olduğu gibi olursa, o zaman mevcut olmayan olası belirsizlikler neden olur ::mu?

C ++, aynı zamanda bir tür adı olan değişken adlarına izin vermediği göz önüne alındığında, bunun olabileceği bir durum düşünemiyorum.

Açıklama: Neden işe yarayabilirse neden ::seçildiğini sormuyorum .?


Yorumlar uzun tartışmalar için değildir; bu sohbet sohbete taşındı .
Samuel Liew

Yanıtlar:


124

C ++ 'ı çoğunlukla mevcut C koduyla (nesne adları ve yapı etiketleri arasında ad çakışmalarına izin verir) uyumlu hale getirme girişimleri nedeniyle, C ++ sınıf adları ve nesne adları arasında ad çakışmalarına izin verir.

Bu şu anlama gelir:

struct data {
    static int member;
};

struct data2 {
    int member;
};

void f(data2& data) {
    data.member = data::member;
}

yasal koddur.


11
Yani başlıktaki sorunun cevabı Evet, olur , değil mi?
Enrico Maria De Angelis

2
@EnricoMariaDeAngelis o kadar basit değil. C ++, Java veya C # gibi tamamen yeni bir dil olarak geliştirildiyse, belirsizlik muhtemelen önlenebilir . Ancak C ++, "sınıflı C" olarak geliştirildi ve bu yüzden değil. "Evet, olacak " doğru bir cevap ama farklı bir soru.
Kit.

Bekleme, atama hattı sadece koyarak gösteren değildir .ya da ::(farklı bir etkiye sahip aynı iki "kelimeler" arasında data.memberbelirtir memberait datasınıfının bir nesne data2ise, data::memberanlamına gelir membersınıfın data)?
Enrico Maria De Angelis

1
Evet, ancak dil tasarımcılarının gurur duyması gereken bir şey değil. Bu sadece uyumluluk kararlarının bir ürünü.
Kit.

Tamam, anlıyorum ki C ++ bugün ve şimdiye kadar (ayrıca) C ++ C + 'dan geliştirilen anda ne olduğunu bağlıdır. Ancak C ++ 'dan olduğu gibi konuşmak ve neden olduğu gibi bir kenara bırakmak, her ::şey değiştiğinde bir belirsizlik olurdu .. Bir şekilde evet yanıtı verdiniz . Sana ilk yorumu ihlal edemem. Belki benim seviyem bu yorumu bana dumanlı gösteriyor.
Enrico Maria De Angelis

37

Her ikisinin de geçerli olduğu, ancak farklı nesnelere başvurduğu bir örnek:

#include <iostream>

struct A {
    int i;
};

struct B {
    int i;
    A B;
};

int main() {
    B x {0, 1};
    std::cout << x.B.i << '\n';
    std::cout << x.B::i << '\n';
}

Bkz canlı coliru .


Ve bu olamazdı kolayca farklı tasarım kararları ile çözülecek!
user253751

7

Ad alanı olarak kullanılan a::bve a.bburada ad alanı veya tür adı anlamına gelen ::ima arasında fark vardır a. C ++ 'ın sanal olmayan çoğul devralmayı desteklemesi ve bir değişkenin bir türle aynı ada sahip olması şartıyla, bu yanlış nesneye gönderme şansını ortadan kaldırır. Şablon meta programlaması için gereklidir.

Başka bir örnek olabilir &B::foovs &B.foosınıf B bağlamında


2

@Deduplicator örneğini genişletelim:

#include <iostream>

struct A {
    int i;
};

struct B : public A {
    int i;
    A A;
};

int main() {
    B x {1, 2};
    std::cout << x.i << '\n';
    std::cout << x.B::i << '\n';  // The same as the line above.
    std::cout << x.A.i << '\n';
    std::cout << x.A::i << '\n';  // Not the same as the line above.
}

Coliru Viewer'da Yayında

Hangi üye ile erişmek istediğimiz :: yardımıyla farklılaşma olanağımız olmadığında, aynı sınıfta bir ebeveyn sınıfında beyan edilen üyelere erişmek imkansızdır.


A A(aynı zamanda bir tür adı olan değişken adı) C ++ için geçerli değildir, bu nedenle bu örnek şu an için geçerli değildir
Jimmy RT

1
JimmyR.T @. Coliru Viewer'da çalışma hayatı örneği var. İfadenizi lütfen standarttan bir paragrafla onaylayın.
SM

Eğer lanetli miras elmasını diğer tarafta aynı şeyle buraya ekleseydi, C ++
Swift - Friday Pie
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.