Sınıf bildirimi küme parantezinden sonra noktalı virgül


82

C ++ sınıflarında, kapanış ayracından sonra neden noktalı virgül? Düzenli olarak unutuyorum ve derleyici hataları alıyorum ve bu nedenle zaman kaybediyorum. Bana biraz gereksiz görünüyor, ki bu durum pek olası değil. İnsanlar gerçekten şu gibi şeyler yapıyor mu:

class MyClass
{
.
.
.
} MyInstance;

Yapılar ve numaralandırmalar için C uyumluluk bakış açısından anlıyorum, ancak sınıflar C dilinin bir parçası olmadığından, sanırım öncelikle benzer bildirim yapıları arasındaki tutarlılığı koru.

İyi bir kod tamamlama IDE'si bunu derlemeden önce yakalayabilirse de, aradığım şey herhangi bir şeyi değiştirebilmekten çok tasarım mantığıyla ilgiliydi.


4
Bu yardımcı olabilir: cpptalk.net/…
Michael Haren

@Michael, bağlantı için teşekkürler. Tarihsel bir perspektiften bakıldığında bu mantıklıdır ve eğer C ++ tüm C gramerine izin veriyorsa ve C ++ sınıfları yapılarla eşanlamlıysa, sınıfın sonunda gerekli noktalı virgül kalır.
SmacL

3
@Brian, evet ciddi bir soru. Bununla yaşamak zorunda olduğumun farkındayım ama tasarımın ve uygulamanın arkasındaki mantığı merak ediyorum.
SmacL

Tamam, ama belki de sorunuzu tasarım mantığını istediğinizi içerecek şekilde düzenlemelisiniz. Olduğu gibi, insanları "neden küme parantezi" gibi sorular sormaya teşvik ediyor? :) Stroustrup's Design & Evolution of C ++ 'ı okumak ilginizi çekebilir, ancak derslerin sonunda noktalı virgüllerden daha ağır konuları kapsar.
Brian Neal

@ Brian, yeterince adil ve wiki yapıp yapmamak konusunda sınırdaydı. Soru, büyük bir yapıda düzenli olarak kullanılan bir başlıkta noktalı virgül bırakıldıktan sonra soruldu. Bana yarım saate mal oldu, dolayısıyla SO ziyareti. Soru, önerinize göre düzenlendi.
SmacL

Yanıtlar:


47

Bir tür bildiriminde kapanış ayracından sonraki noktalı virgül, dil tarafından gereklidir. C'nin en eski versiyonlarından beri böyleydi.

Ve evet, insanlar sizin az önce ortaya koyduğunuz beyanı gerçekten yapıyorlar. Yöntemlerin içinde kapsamlı türler oluşturmak için kullanışlıdır.

void Example() {
  struct { int x; } s1;
  s1.x = 42;

  struct ADifferentType { int x; };
}

Bu durumda, noktalı virgüllere neden ihtiyaç duyulduğunun açık olduğunu düşünüyorum. Başlık dosyasında beyan etmenin daha genel bir durumda neden gerekli olduğuna gelince, emin değilim. Benim tahminim bu tarihsel olduğunu ve daha kolay derleyici yazılmasını sağlamak için yapılır olmasıdır.


Neden MyInstance'ı belirtmeden kapsamlı tür oluşturamıyorum? İki eylemi birleştirdiğinizde tuhaf görünüyor: yeni tür bildirmek ve yeni değişken bildirmek.
Mykola Golubyev

@Mykola ikisini de yapabilirsiniz. Eklediğim örneğe bakın
JaredPar

71

Bağlantı @MichaelHaren tarafından sağlanan sağlamak için görünen temel nedenini . Noktalı virgül (diğerlerinin de belirttiği gibi) C'den miras alınmıştır. Ancak bu, C'nin ilk başta neden onu kullandığını açıklamaz. Tartışma, bir örneğin cevherini içerir:

struct fred { int x; long y; }; 
main() 
{ 
  return 0; 
} 

C'nin eski sürümleri, aksi belirtilmedikçe bir işlevden örtük bir dönüş türüne sahipti. ;Yapı tanımının sonunda atlarsak, sadece yeni bir tür tanımlamakla fredkalmıyor, aynı zamanda bunun main()bir örneğini döndüreceğini de bildiriyoruz fred. Yani kod şu şekilde ayrıştırılır:

struct fred { int x; long y; } main()
{ 
  return 0; /* invalid return type, expected fred type */
} 

1
Evet, örtük int dönüş türü burada her şeyi etkiliyor. Güzel mücevher
Gaspa79

17

Sanırım sınıflar, gruplama için parantezlere ihtiyaç duyduklarında bile bildirimlerdir. Ve evet, C'den beri yapabileceğiniz tarihsel bir argüman var

struct
{
  float x;
  float y;
} point;

C ++ 'da benzer bir şey yapabilmelisiniz, classbildirimin aynı şekilde davranması mantıklıdır .


11

Kısaltması

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

Sınıf bildiriminin kaşlı ayraçlarından sonraki noktalı virgül aslında aşırıdır, ancak C ++ bu şekilde tanımlanır. Değişken bildiriminden sonraki noktalı virgül her zaman gereklidir ve anlamlıdır.


1
Öyleyse, C ++ her bildirimden sonra noktalı virgül gerektirir mi?
Loai Nagati

1
Bu şekilde, anonim bir sınıfın nesnesini oluşturamazken, diğer şekilde yapabileceğinizi unutmayın.
Kevin

5

Bu tür beyanları kullanmıyorum

class MyClass
{
.
.
.
} MyInstance;

Ama bu durumda neden orada noktalı virgül olduğunu anlayabiliyorum.
Çünkü int a;değişken bildirimine benzer.

Muhtemelen tutarlılık için 'MyInstance' noktalı virgülü atlayabildiğiniz için orada kalır.


3

A'dan sonra structuyumluluk nedenleriyle gereklidir ve bunu nasıl istersiniz:

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency

1
Peki ya ne olacak namespace myNamespace { ... } // inconsistent but valid?
Chris K

3

C / C ++ 'da; bir ifade sonlandırıcıdır. Tüm ifadeler; belirsizliği önlemek (ve ayrıştırmayı basitleştirmek için). Dilbilgisi bu açıdan tutarlıdır. Bir sınıf bildirimi (veya bu konudaki herhangi bir blok) birden çok satır uzunluğunda olsa ve {} ile sınırlandırılmış olsa da, yine de basitçe bir ifadedir ({} ifadenin parçasıdır) bu nedenle ile sonlandırılması gerekir; (; Bir ayırıcı / sınırlayıcı değildir)

Senin örneğinde

class MyClass{...} MyInstance;

tam bir ifadedir. Tek bir ifadede beyan edilen sınıfın birden çok örneği tanımlanabilir

class MyClass{...} MyInstance1, MyInstance2;

Bu, tek bir ifadede bir ilkel türün birden çok örneğini bildirmekle tamamen tutarlıdır:

int a, b, c;

Kişinin bu tür sınıf ve örnek tanımlamasını sıklıkla görmemesinin nedeni, örnek olabilir mi? global bir değişken olun ve statik ve / veya Düz Eski Veri yapıları olmadıkça global nesneleri gerçekten istemezsiniz.


2
Ancak işlev tanımı da bir ifadedir ancak noktalı virgül içermez.
Jiapeng Zhang
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.