it-swarm-tr.com

C ++ 'daki struct ve class arasındaki farklar nelerdir?

Bu soru C # /. Net bağlamında zaten sorulmuşt .

Şimdi C++ 'da bir yapı ve bir sınıf arasındaki farklılıkları öğrenmek istiyorum. Lütfen teknik farklılıkları ve bunlardan birini veya diğerini seçme nedenlerini OO design'da tartışın.

Bariz bir fark ile başlayacağım:

  • public: veya private: belirtmezseniz, yapı üyeleri varsayılan olarak geneldir; bir sınıfın üyeleri varsayılan olarak özeldir.

C++ teknik özelliklerinin belirsiz köşelerinde bulunabilecek başka farklılıklar olduğuna eminim.

414
palm3D

Sınıflar ve yapılar arasındaki zor 2. farkı unutuyorsunuz.

Standardı belirtiniz (§11.2.2, C++ 98 ila C++ 11):

Bir temel sınıf için bir erişim belirteci yoksa, türetilmiş sınıfın bildirildiği zaman genel varsayılır struct ve sınıf ilan edildiğinde özel kabul edilir sınıf .

Ve sadece bütünlük uğruna, sınıf ve yapı arasındaki daha yaygın olarak bilinen fark (11.2) 'de tanımlanmıştır:

Anahtar sözcükle tanımlanmış bir sınıfın üyesi sınıf , varsayılan olarak özel . Anahtar kelimelerle tanımlanan bir sınıfın üyeleri struct veya union are genel varsayılan olarak.

Ek fark: class anahtar kelimesi, şablon parametrelerini bildirmek için kullanılabilirken, struct anahtar sözcüğü bu şekilde kullanılamaz.

449
Assaf Lavie

Alıntı Yapma C++ SSS ,

[7.8] struct ve class anahtar sözcükleri arasındaki fark nedir?

Bir yapının üyeleri ve temel sınıfları varsayılan olarak geneldir, sınıfta ise varsayılan olarak özeldir. Not: Temel sınıflarınızı varsayılanlara güvenmek yerine açıkça kamuya açık, özel veya korumalı hale getirmelisiniz.

Yapı ve sınıf aksi takdirde işlevsel olarak eşdeğerdir.

Tamam, o kadar gıcırtılı temiz tekno konuşması. Duygusal olarak, çoğu geliştirici bir sınıf ve bir yapı arasında güçlü bir ayrım yapar. Bir yapı, enkapsülasyon veya işlevsellik yolunda çok az olan açık bir bit yığını gibi hissediyor. Bir sınıf, akıllı hizmetler, güçlü bir kapsülleme engeli ve iyi tanımlanmış bir arayüz ile toplumun yaşayan ve sorumlu bir üyesi gibi hissediyor. Zaten çoğu kişinin sahip olduğu çağrışım bu olduğundan, çok az yöntem içeren ve genel veriye sahip bir sınıfa sahipseniz (iyi tasarlanmış sistemlerde bu tür şeyler var!), Muhtemelen struct anahtar sözcüğünü kullanmalısınız. anahtar kelime.

157
Robᵩ

C++ 'nın kökenlerini ve C. ile uyumluluğunu hatırlamakta fayda var.

C'nin yapıları vardır, kapsülleme kavramı yoktur, bu yüzden her şey halka açıktır.

Nesne yönelimli bir yaklaşım alırken varsayılan olarak halka açık olmak genellikle kötü bir fikir olarak kabul edilir, bu nedenle, doğal olarak OOP 'e elverişli olan bir C formunda (C içinde OO yapabilirsiniz. , ancak C++ 'ta (aslen "C With Classes") fikir olan, size yardımcı olmayacaktır. Üyeleri varsayılan olarak özel yapmak mantıklıdır.

Öte yandan, eğer Stroustrup struct 'nin anlamını değiştirmiş olsaydı, üyeleri varsayılan olarak özel olacaktı ki, uyumsuzluğu bozulacaktı (standartlar değiştiği kadar sık ​​değil, fakat tüm geçerli C programları da geçerli C++ programlarıydı.) C++ 'a bir ayak izi vermede büyük etkisi vardı).

Bu yüzden class adlı yeni bir anahtar kelime tam olarak bir yapıya benzer, ancak varsayılan olarak özel olarak tanıtıldı.

Eğer C++ sıfırdan başlamış, geçmişsiz olsaydı, muhtemelen tek bir anahtar kelime olurdu. Ayrıca, muhtemelen yarattığı etkiyi de yaratmazdı.

Genel olarak, insanlar yapıların C'de nasıl kullanıldığı gibi bir şey yaparken yapı kullanma eğiliminde olacaktır; Herkese açık üyeler, hiçbir kurucu (bir sendika içinde olmadığı sürece), , , tıpkı sınıflarda olduğu gibi, yapılarda kuruculara sahip olabilirsiniz; değil), sanal yöntem yok, vb. Dillerin kodları okuyan insanlarla makinelere talimat verecek kadar iletişim kurmaları (ya da başka bir deyişle Meclis ve sadık kaldıklarımızla VM opcodes] olması iyi bir fikirdir. buna sadık kalmak.

115
Jon Hanna

Sınıf 'üyeleri varsayılan olarak özeldir. Struct üyeleri varsayılan olarak herkese açıktır. Bunun yanında başka hiçbir fark yoktur. Ayrıca bakınız bu sor .

31
Kasprzol

Stroustrup'a göre C++ Programlama Dili :

Hangi tarzı kullandığınız şartlara ve zevkinize bağlıdır. Genelde tüm verileri içeren sınıflar için struct işlevini kullanmayı tercih ederim. Bu tür sınıfları "oldukça uygun tipler değil, sadece veri yapıları" olarak düşünüyorum.

İşlevsel olarak, kamudan/özelden başka bir fark yoktur.

28
crashmstr

YAPI, belirli bir bellek yığınını yapı özelliklerine göre ayıran bir Soyut Veri Tipi türüdür. Yapılar, genellikle dosyaya yazılı olarak yazılabildiğinden, yapılar seri hale getirme/seri kaldırma işlemlerinde özellikle kullanışlıdır. (diğer bir deyişle, yapıya bir işaretçi alın, kopyalanacak bayt sayısını hesaplamak için SIZE makrosunu kullanın, sonra verileri yapı içine veya dışına taşıyın.)

Sınıflar, bilgilerin gizlenmesini sağlamaya çalışan farklı türde bir soyut veri türüdür. Dahili olarak, çeşitli işleme, yöntemler, geçici değişkenler, durum değişkenleri olabilir. vb. sınıfı kullanmak isteyen herhangi bir koda tutarlı bir API sunmak için kullanılır.

Aslında, yapılar veri ile ilgili, sınıflar kod ile ilgilidir.

Ancak, bunların yalnızca soyutlamalar olduğunu anlamanız gerekir. Çok yapıya benzeyen sınıflara ve sınıflara benzeyen yapılar oluşturmak mükemmel bir şekilde mümkün. Aslında, en eski C++ derleyicileri yalnızca C++ kodunu C'ye çeviren ön derleyicilerdi. Bu nedenle bu soyutlamalar, mantıksal düşünmenin bir yararı değil, bilgisayarın kendisi için bir varlık değil.

Her birinin farklı bir soyutlama türü olmasının ötesinde, Sınıflar C kodu adlandırma bulmacasına çözümler sunar. Aynı ada sahip birden fazla işleve sahip olamadığınız için, geliştiriciler _ () modelini izlerdi. Örneğin. mathlibextreme_max (). API'leri sınıflara ayırarak benzer işlevler (burada "yöntemler" olarak adlandırıyoruz) birlikte gruplandırılabilir ve diğer sınıflardaki yöntemlerin isimlendirilmesinden korunabilir. Bu, programcının kodunu daha iyi düzenlemesine ve kodun yeniden kullanımını artırmasına olanak tanır. Teoride, en azından.

9
64BitBob

1) Bir sınıfın üyeleri varsayılan olarak özeldir ve yapı üyeleri varsayılan olarak herkese açıktır.

Örneğin, program 1 derleme başarısız olur ve program 2 iyi çalışıyor.

// Program 1
#include <stdio.h>

class Test {
    int x; // x is private
};
int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
Run on IDE
// Program 2
#include <stdio.h>

struct Test {
    int x; // x is public
};
int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

2) Bir sınıf/yapıdan bir yapı türetirken, bir temel sınıf/yapı için varsayılan erişim belirteci geneldir. Ve bir sınıf türetirken, varsayılan erişim belirteci özeldir.

Örneğin, program 3 derleme başarısız olur ve program 4 iyi çalışıyor.

// Program 3
#include <stdio.h>

class Base {
public:
    int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base {}

int main()
{
  Derived d;
  d.x = 20; // compiler error becuase inheritance is private
  getchar();
  return 0;
}
Run on IDE
// Program 4
#include <stdio.h>

class Base {
public:
    int x;
};

struct Derived : Base { }; // is equilalent to struct Derived : public Base {}

int main()
{
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}
9
Suraj K Thomas

Diğer tek fark, şaşırtıcı bir şekilde sırasıyla özel ve halka açık olan sınıfların ve yapıların varsayılan mirasıdır.

8
Skizz
  1. Bir yapının üyeleri varsayılan olarak geneldir, sınıf üyeleri varsayılan olarak özeldir.
  2. Başka bir yapı veya sınıftan Yapı için varsayılan miras, geneldir.
class A{    
public:    
    int i;      
};

class A2:A{    
};

struct A3:A{    
};


struct abc{    
    int i;
};

struct abc2:abc{    
};

class abc3:abc{
};


int _tmain(int argc, _TCHAR* argv[])
{    
    abc2 objabc;
    objabc.i = 10;

    A3 ob;
    ob.i = 10;

    //A2 obja; //privately inherited
    //obja.i = 10;

    //abc3 obss;
    //obss.i = 10;
}

Bu VS2005'te.

4
GirishNayak

Unutulmaması gereken başka bir şey, sınıfları kullanmak için yapıları olan eski bir uygulamayı güncellediyseniz, aşağıdaki sorunla karşılaşabilirsiniz:

Eski kodun yapıları var, kod temizlendi ve bunlar sınıflara dönüştürüldü. Yeni güncellenmiş sınıfa sanal bir işlev veya iki eklenmiştir.

Sanal işlevler sınıftayken, dahili olarak derleyici, işlevleri işaret etmek için sınıf verilerine ekstra işaretçi ekleyecektir.

Bunun eski miras kodunu nasıl bozacağı, eski kodda herhangi bir yerdeki yapının hepsini sıfırlamak için doldurma kullanarak temizlenmiş olması durumunda, bu ilave işaretçi verilerini de durduracaktı.

4
KPexEA

Spesifikasyonda yok, hayır. Temel fark, kodunuzu 2 yıl içinde okuduklarında programcı beklentileridir. yapılar genellikle POD olarak kabul edilir. Yapılar, ayrıca, nesneleri tanımlamaktan başka amaçlar için bir tür tanımlarken şablon meta programlamasında da kullanılır.

4
MSalters

Bir başka önemli fark ise Şablonlara gelincedir. Bildiğim kadarıyla, bir şablon tanımlarken bir yapı tanımlarken bir sınıf kullanabilirsiniz.

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
3
Stefan Popescu

Bu sadece bir kongre. Basit veriyi tutacak yapılar oluşturulabilir ancak daha sonra üye işlevlerin ve kurucuların eklenmesiyle zaman gelişir. Öte yandan, halktan başka bir şey görmek sıra dışı: bir yapıya erişim.

2
finnw

ISO IEC 14882-2003

9 Sınıflar

§3

Yapı, class-key struct; üyeleri ve temel sınıfları (fıkra 10) varsayılan olarak herkese açıktır (fıkra 11).

2
Gregory Pakosz
  1. class anahtar sözcüğü ile tanımlanan bir sınıfın üyesi, varsayılan olarak private'dir. struct (veya union) anahtar sözcükleriyle tanımlanan bir sınıfın üyeleri varsayılan olarak public'dir.

  2. Bir temel sınıf için bir erişim belirteci olmadığında, türetilmiş sınıf ilan edildiğinde public, sınıf struct olarak ilan edildiğinde private ve class kabul edilir.

  3. Bir enum class belirtebilirsiniz, ancak bir enum struct belirtemezsiniz.

  4. template<class T> öğesini kullanabilirsiniz, ancak template<struct T> öğesini değil.

Ayrıca, C++ standardının, bir türü struct olarak bildirmesini ve ardından türünü bildirirken class kullanmanıza izin verdiğini unutmayın. Ayrıca, std::is_class<Y>::value, Y'nin true ve struct olması için class'dir, ancak enum class için false'dir.

2
Bathsheba

İşte iyi bir açıklama: http://carcino.gen.nz/tech/cpp/struct_vs_class.php

Dolayısıyla, bir kez daha: C++ 'da, bir yapı, bir yapı üyesinin varsayılan olarak kamu görünürlüğüne sahip olması dışında bir sınıfla aynıdır, ancak bir sınıfın üyeleri varsayılan olarak özel görünürlük sahibidir.

2
nutario
  • . Sınıflarda tüm üyeler varsayılan olarak özeldir, ancak yapı üyelerinde varsayılan olarak herkese açıktır.

    1. Yapılar için yapıcı ve yıkıcı gibi bir terim yoktur, ancak sağlamadığınız takdirde sınıf derleyici için varsayılan oluşturur.

    2. Sizeof empty yapısının 0 baytı, Sizeof empty class 1 bayttır. Yapısal varsayılan erişim türü herkese açıktır. Bir yapı tipik olarak verileri gruplamak için kullanılmalıdır.

    Sınıf varsayılan erişim türü özeldir ve devralma için varsayılan mod özeldir. Verileri ve bu veriler üzerinde çalışan yöntemleri gruplamak için bir sınıf kullanılmalıdır.

    Kısacası, sözleşme, amaç veriyi gruplandırırken yapıyı kullanmak ve veri soyutlama ve belki de mirasa ihtiyaç duyduğumuzda sınıfları kullanmaktır.

    C++ 'da yapılar ve sınıflar açıkça belirtilmedikçe değere göre iletilir. Diğer dillerde, sınıflar ve yapılar farklı anlamlara sahip olabilir - yani. nesneler (sınıfların örnekleri) referans olarak ve yapılar değer olarak geçirilebilir. Not: Bu soru ile ilgili yorumlar var. Konuşmaya eklemek için tartışma sayfasına bakın.

1
yshivakathik

class ve struct arasındaki fark, veri türleri arasında değil, anahtar kelimeler arasındaki farktır. Bu iki

struct foo : foo_base { int x;};
class bar : bar_base { int x; };

her ikisi de bir sınıf tipi tanımlar. Bu bağlamdaki anahtar kelimelerin farkı, farklı varsayılan erişimdir:

  • foo::x genel ve foo_base genel olarak devralındı
  • bar::x özel ve bar_base özel olarak miras kaldı

Diğer cevaplar tarafından ima edilmekle birlikte, açıkça belirtilmemiştir - yapıların kullanıma bağlı olarak C uyumludur; sınıflar değil.

Bunun anlamı, C ile uyumlu olmak istediğiniz bir başlık yazıyorsanız, yapıdan başka seçeneğiniz yoktur (C dünyasında fonksiyonlara sahip olamaz; ancak fonksiyon işaretçilerine sahip olabilir).

1
UKMonkey

Diğer cevaplar özel/genel varsayılanlardan bahsetti (ancak bir yapının bir sınıf bir yapı olduğuna dikkat edin; iki farklı öğe değil, aynı öğeyi tanımlamanın sadece iki yolu).

Unutulmaması gereken ilginç bir konu (özellikle askerin "yönetilmeyen" C++ 'dan bahsettiği için MSVC++ kullanması muhtemel olduğu için), eğer bir sınıf class ile bildirilirse ve daha sonra struct (veya muhtemelen diğeri ile tanımlanırsa) belirli koşullar altında şikayet eder. yol boyunca), standart bunun tamamen yasal olduğunu söylese de.

1
ymett