C ++ yapı ve sınıf arasındaki farklar nelerdir?


441

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

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

Açık bir farkla başlayacağım:

  • Belirtmezseniz public:veya private:bir yapının üyeleri varsayılan olarak herkese açıktır; sınıf üyeleri varsayılan olarak gizlidir.

C ++ belirtiminin belirsiz köşelerinde bulunacak başka farklılıklar olduğundan eminim.


6
Bu bağlantı farklılıkları iyi özetlemektedir.
sjsam

1
Neden insanlar o zaman bir ağaç inşa etmek için yapıyı kullanıyor? Çünkü fark o kadar da değil. BTW, Bu harika bir web sitesi. @ Sjsam
JW.ZG

1
structC ve C ++ arasındaki farkı mı arıyorsunuz? Buraya bakın .
Marc.2377

@ JW.ZG "Herkes" değil! Bunu yapanlar ya structC ++ 'ta ne anlama geldiğini ya da ne anlama geldiğini bilmiyorlar . ;) Ancak classbunun yerine anahtar kelimeyi kullanamazsınız .
Yörüngedeki Hafiflik Yarışları

Yanıtlar:


466

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

Standart getirin (C ++ 98'den C ++ 11'e §11.2.2):

Bir yokluğunda erişim-şartname türetilmiş bir sınıf bildirirken bir temel sınıf için, halka varsayılır yapı ve özel sınıfı bildirirken varsayılır sınıfı .

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

Anahtar kelime ile tanımlanan bir sınıfın üyesi sınıfında olan özel varsayılan olarak. Struct veya union anahtar sözcükleriyle tanımlanan bir sınıfın üyeleri varsayılan olarak herkese açıktır .

Ek fark: Anahtar kelime classbu şekilde kullanılamazken , anahtar kelime şablon parametrelerini bildirmek structiçin kullanılabilir.


22
Bu gerçekten ikinci bir fark değil, sadece sorunun farkı tam olarak ifade etmemesi. Tüm alt nesneler varsayılan olarak özeldir, varsayılan olarak classgenel ile birlikte kullanılır structve her ikisi de bir sınıf türü tanımlar.
Ben Voigt

10
Sanırım bu noktayı kaçırdın, Ben. Yapılar için halka açık ve sınıflar için özel olan miras. Bu çok önemli bir ayrım ve gerçek üye erişimi ile tamamen ilgisiz. Örneğin, dil çok iyi tanımlamış olabilir, örneğin her ikisi de varsayılan olarak herkese açık olarak devralınır ve çok farklı sonuçlar elde edersiniz.
Assaf Lavie

104
Aslında, gerçek zor arasındaki fark structve classikincisi bir yerine kullanılabilecek olmasıdır typenameşablon parametresi ilan etmek, eski teneke yaparken değil. :)
sbi

21
@MrUniverse: Bu tamamen yanlış. (Bunu bir kongre için kullanan bir okul var, ancak sözdizimsel olarak uygulanmıyor.)
sbi

3
@sbi "yapı ve sınıf arasındaki gerçek zor fark" - Sevimli, ancak söz arasındaki fark hakkında bir yapı ve bir anahtar kelimeleri değil kullanılabilir nerede farklar hakkında sınıfında.
Jim Balter

161

C ++ SSS'sinden alıntı yapmak ,

[7.8] struct ve class anahtar kelimeleri arasındaki fark nedir?

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

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

Tamam, o gıcırtılı temiz tekno konuşmasından yeterince. Duygusal olarak, çoğu geliştirici sınıf ve yapı arasında güçlü bir ayrım yapar. Bir yapı, kapsülleme veya işlevsellik yolunda çok az olan açık bir bit yığını gibi hisseder. Bir sınıf, akıllı hizmetler, güçlü bir kapsülleme engeli ve iyi tanımlanmış bir arayüzle toplumun yaşayan ve sorumlu bir üyesi gibi hissediyor. Çoğu insanın zaten sahip olduğu çağrışım olduğundan, çok az yöntemi olan ve genel verilere sahip bir sınıfınız varsa (böyle şeyler iyi tasarlanmış sistemlerde var!) Büyük olasılıkla struct anahtar sözcüğünü kullanmalısınız, aksi takdirde sınıfı kullanmalısınız anahtar kelime.


123

C ++ 'ın C'nin kökenini ve onunla uyumluluğunu hatırlamakta fayda var.

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

Varsayılan olarak kamuya açık olmak, nesne yönelimli bir yaklaşım alırken genellikle kötü bir fikir olarak kabul edilir, bu nedenle yerel olarak OOP'ye elverişli bir C formu yaparken (C'de OO yapabilirsiniz, ancak size yardımcı olmaz) C ++ (başlangıçta "C With Classes") fikri, varsayılan olarak üyeleri özel yapmak mantıklıdır.

Öte yandan, Stroustrup structüyelerinin anlamlarını varsayılan olarak özel olacak şekilde değiştirmiş olsaydı, uyumluluğu bozmuş olurdu (standartlar ayrıldığı kadar sık ​​doğru değil, ancak tüm geçerli C programları da geçerli C ++ programlarıydı, C ++ 'ın dayanak noktası üzerinde büyük etkisi olan).

Böylece yeni bir anahtar kelime, classtam olarak bir yapı gibi, ancak varsayılan olarak özel olacak şekilde tanıtıldı.

C ++ hiçbir geçmişi olmayan sıfırdan gelmiş olsaydı, muhtemelen böyle bir anahtar kelimeye sahip olurdu. Muhtemelen yaptığı etkiyi yaratmazdı.

Genel olarak, insanlar yapıların C'de nasıl kullanıldığı gibi bir şey yaparken yapı kullanma eğilimi gösterir; kamu üyeleri, kurucu yok (bir birlikte olmadığı sürece , sınıflarda olduğu gibi yapılarda yapıcılara sahip olabilirsiniz , ancak insanlar yapmazlar), sanal yöntemler vb. makinelere talimat vermek için kodu okuyan insanlar (veya montaj ve ham VM opcodes'larına bağlı kalacağız) buna uymak iyi bir fikirdir.


Muhtemelen, sınıfların ve yapıların kaputun altında aynı şekilde çalışmasının, temelde farklı olmalarından daha kolay olduğunu belirtmek gerekir. Geriye dönüp bakıldığında, örneğin bir yapı olarak bildirilen herhangi bir şeyin bir PODS (yani sanal üyelere, önemsiz olmayan varsayılan kuruculara veya yıkıcılara sahip olmalarını yasaklamak) olması gerektiğini belirtmenin bir yararı olabilirdi, ancak böyle bir şey bilgim için değil herhangi bir C ++ standardı veya uygulaması gerektirmez.
supercat

1
@OO olmayan bir dilde yazılmış geniş bir program repertuarının geçerli programlar olduğu, konsepti öne çıkardığı ve daha saf OO dillerinden daha fazla ortaya çıktığı görülüyor. (ve elbette standartta tanımlanmıştır). Erken C ++ tarihi kesinlikle bu konuda çok şey açıklıyor. Stroustrup'un "C ++ Tasarımı ve Evrimi" ilginç bir okuma.
Jon Hanna

1
"Oop-ish" olmayan her şeyin olması gerektiğini düşünen ve OOP'un bir araç olarak değil , bir araç olarak görülmesi gerektiğini düşünenler arasında dini bir savaş olduğunu düşünüyorum . C ++ kesinlikle ikinci felsefeyi kucaklıyor gibi görünüyor, ama bundan önce diller hakkında çok fazla şey bilmiyorum. Kendi felsefem, kişi bir nesne istediğinde, bir nesne kullanmalı ve kişi ilişkili ancak bağımsız değişkenlerin bir araya gelmesini istediğinde, bunu kullanmalıdır. C ++, bu tür şeyler arasında sözdizimsel bir ayrım
yapmaz

1
... C ++ veya .NET'ten daha iyi tanıdığını önerir. Değişkenlerin toplanması tam olarak OOPish değildir, ancak bu yararlı olduklarında çalıştırılmamaları gerektiği anlamına gelmez .
supercat

3
"C'nin yapıları var, kapsülleme kavramı yok, bu yüzden her şey herkese açık" diye katılmıyorum. Bir struct*.cdosyanın tanımını gizleyebilir ve diğer çeviri birimlerinin yalnızca bir işaretçi ile kullanmasına izin verebilirsiniz . Böylece daha güçlü bir kapsülleme yapıyorsunuz, çünkü diğer çeviriler birimin içinde ne olduğunu bile bilmiyorlar struct.
12431234123412341234123

32

Sınıf üyeleri varsayılan olarak gizlidir. Yapı üyeleri varsayılan olarak herkese açıktır. Bunun dışında başka bir fark yok. Ayrıca bu soruya bakın .


15
Sadece üyeler değil, miras dahil tüm erişim.
Nemanja Trifunovic

4
Diğer farkın anlambilim olduğunu söyleyebilirim. Birçok insan için Yapılar onları "veri yapısı" C bir artık olarak
düşünmelerini sağlar

3
@KrisKumler: Bunlar "anlambilim" değil; onlar kişisel duygulardır. Her ikisi de structve aynı anlamsallığa sahip classbir sınıf ilan ederler (tanım gövdesinin ayrıştırmalı yorumuna rağmen).
Yörüngedeki Hafiflik Yarışları

28

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

Hangi stili kullandığınız, koşullara ve zevkinize bağlıdır. Genellikle structtüm verileri herkese açık olan sınıflar için kullanmayı tercih ederim . Bu sınıfları "oldukça uygun tipler değil, sadece veri yapıları" olarak düşünüyorum.

İşlevsel olarak, kamu / özel sektörden başka bir fark yoktur.


32
Ne farkı? Lütfen açıkla.
crashmstr

10

STRUCT, belirli bir bellek yığınını yapı spesifikasyonuna göre ayıran bir Soyut Veri Türü türüdür. Yapılar genellikle dosya kelimesi kelimesine yazılabildiğinden, dosya serileştirme / serileştirme işleminde özellikle yararlıdır. (yani yapıya bir işaretçi alın, kopyalanacak bayt sayısını hesaplamak için SIZE makrosunu kullanın, ardından verileri yapı içinde veya dışına taşıyın.)

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

Aslında, yapılar verilerle, sınıflar kodla ilgilidir.

Ancak, bunların sadece soyutlamalar olduğunu anlamanız gerekir. Sınıflara çok benzeyen yapılar ve yapılara çok benzeyen sınıflar oluşturmak mükemmel bir şekilde mümkündür. Aslında, en eski C ++ derleyicileri sadece C ++ kodunu C'ye çeviren ön derleyicilerdi.

Her biri 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 olamayacağınız için, geliştiriciler _ () örüntüsünü izlerlerdi. örneğin mathlibextreme_max (). API'ları sınıflara ayırarak, benzer işlevler (burada bunlara "yöntemler" diyoruz) birlikte gruplandırılabilir ve diğer sınıflardaki yöntemlerin adlandırılmasından korunabilir. Bu, programcının kodunu daha iyi organize etmesini ve kodun yeniden kullanımını artırmasını sağlar. Teoride, en azından.


1
Bu, yapılar ve sınıflar hakkında en açık olmayan şeydir. "Yapılar verilerle ilgili, sınıflar kodla ilgili" olarak yeniden yapılandırılabilir "yapılar verilerle ilgili, sınıflar verilerle, güvenlikle ve bu verilerle yapılan işlemlerle ilgili"
Arun Aravind

3
C ++ 'da bir yapı oluşturmak mümkün değildir. Yalnızca devralınan structanahtar kelimeyi kullanarak bir sınıf oluşturmak mümkündür .
Orbit'te Hafiflik Yarışları

1
Bu cevap C ++ ile ilgili görünmüyor. C ++ 'da structsınıfları bildirir ( public/ private/ protected, kalıtım vb. Dahil ).
melpomene

Yapılar nasıl özetlenir? Ham yapıları bir dosyaya yazmak C'de bile problemlerle doludur (olağan problemler arasında dolgu, endianite, farklı kelime boyutu vb.) Bulunur. SIZEBahsettiğiniz bu makro nedir ?
melpomene

10

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 derlemede başarısız oluyor 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) Sınıf / yapıdan bir yapı türetilirken, temel sınıf / yapı için varsayılan erişim belirteci herkese açıktır. Bir sınıf türetirken, varsayılan erişim belirteci özeldir.

Örneğin program 3 derlemede başarısız oluyor 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;
}

Uzmanlar tarafından belirtildiği gibi 3-7 kod örneklerini kaldırdım
Suraj K Thomas

8

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


5
  1. Bir yapının üyeleri varsayılan olarak herkese açıktır, sınıf üyeleri varsayılan olarak özeldir.
  2. Başka bir yapı veya sınıftan Yapı için varsayılan miras geneldir. Başka bir yapı veya sınıftan sınıf için varsayılan miras özeldir.
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.


_tmainstandart C ++ değildir.
17'de

4

Spesifikasyonda değil, hayır. Temel fark, kodunuzu 2 yıl içinde okuduklarında programcı beklentilerindedir. yapıların genellikle POD olduğu varsayılır. Yapılar, nesneleri tanımlamaktan başka amaçlar için bir tür tanımlarken şablon meta programlamasında da kullanılır.


4

Dikkat edilmesi 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ı vardır, kod temizlendi ve bunlar sınıflara değiştirildi. Daha sonra yeni güncellenen sınıfa bir veya iki sanal işlev eklendi.

Sanal işlevler sınıflardayken, derleyici işlevlere işaret etmek için sınıf verilerine ekstra işaretçi ekler.

Bunun eski eski kodu nasıl kıracağı, eski kodda bir yerde, yapıları sıfırlarla temizlemek için memfill kullanılarak temizlenmişse, bu ekstra işaretçi verilerini de durduracaktır.


1
Bir yapıyı temizlemek için memfill kullanan kod muhtemelen başka rahatsız edici alışkanlıklara sahiptir. Dikkatli olun.
David Thornley

@DavidThornley: Bir veri yapısını silmek veya başlatmak için sıfır dolgusunun kullanılması C'de standarttır. Karışık dilli bir projede, C bölümündeki kodun calloclehine kaçınması beklenemez new. Yapabileceği tek şey, kodun C kısmı tarafından kullanılan herhangi bir yapının aslında PODS olmasını sağlamaktır.
supercat

4
  1. Anahtar sözcüğüyle tanımlanan bir sınıfın üyesi classolan privatevarsayılan olarak. Anahtar kelimelerle struct(veya union) tanımlanmış bir sınıfın üyeleri publicvarsayılan olarak vardır.

  2. Bir taban sınıfı için bir erişim belirtici yokluğunda, publiczaman olduğu varsayılır türetilmiş sınıf ilan edilir structve privatesınıf bildirirken varsayılır class.

  3. Bir ilan edebilirsin enum classama değil enum struct.

  4. Kullanabilirsin template<class T>ama kullanamazsın template<struct T>.

Ayrıca C ++ standardının bir türü a olarak bildirmenize structve daha sonra classtürü bildirirken kullanmanıza izin verdiğini unutmayın. Aynı zamanda, std::is_class<Y>::valuebir trueY, bir olduğu için structve bir class, ama falsebir için enum class.


güzel cevap, ben açık bir belirgin eksik olsa da 0) structve classc ++ arasındaki fark veri türleri (veya bazı daha iyi bir alternatif;) arasında değil, anahtar kelimeler arasındaki
farktır

@ formerlyknownas_463035818: Ama sence bunu std::is_class<Y>::valuekapsamıyor mu?
Bathsheba

evet, sadece daha belirgin olabileceğini düşündüm, çünkü bu yaygın yanlış anlama ve bir zamanlar geri kalan yol sadece corollaries.
idclev 463035818

Nevermind, cevabınız mükemmel, başka bir tane yazdım, bir tane daha incitmez
idclev 463035818

4

Arasındaki fark classve structanahtar kelimeler arasındaki değil, veri türleri 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 türü tanımlar. Bu bağlamdaki anahtar kelimelerin farkı, farklı varsayılan erişimdir:

  • foo::xherkese açıktır ve foo_basealenen miras alır
  • bar::xbar_baseözeldir ve özel olarak devralınır


2

Bu sadece bir kongre. Yapılar basit verileri tutmak için oluşturulabilir ancak daha sonra üye fonksiyonlar ve yapıcıların eklenmesiyle zaman içinde gelişir. Öte yandan, kamu dışında bir şey görmek olağandışı: bir yapıya erişim.


2

ISO IEC 14882-2003

9 Sınıf

§3

Yapı, sınıf anahtarıyla tanımlanan bir sınıftır struct; üyeleri ve temel sınıflar (madde 10) varsayılan olarak herkese açıktır (madde 11).


2

Başka bir temel fark Şablonlar söz konusu olduğundadır. Bildiğim kadarıyla, bir şablon tanımlarken bir yapı değil bir sınıf kullanabilirsiniz.

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

1
Yapıların genelleştirilmiş türler olarak kullanılamayacağını vurgulamayı amaçladıysanız, yanlışsınız demektir. Ve structsadece konvansiyon tarafından izin verilmez ( classburada farklı anlamda kullanılan anahtar kelime olduğunu varsayalım , bkz . Şablon parametreleri için 'sınıf' veya 'typename' kullanma ).
dma_k

Anahtar kelimeye orada izin verilmez, ancak tanımladığınız bir sınıfı structiyi bir şekilde iletebilirsiniz . Sadece dene. struct T{}; template <typename T> void foo() {} foo<T>();
Yörüngedeki Hafiflik Yarışları

1

Diğer yanıtlar özel / genel varsayılanlardan bahsetmiştir (ancak bir yapının bir sınıf bir yapı olduğunu unutmayın; bunlar iki farklı öğe değildir, aynı öğeyi tanımlamanın iki yolu vardır).

İlginç olan şey (özellikle asker "yönetilmeyen" C ++ 'dan bahsettiği için MSVC ++ kullanması muhtemeldir), Visual C ++' ın bir sınıfın ilan edilmesi classve daha sonra tanımlanması struct(veya muhtemelen başka bir şekilde) ), standart bunun tamamen yasal olduğunu söylese de.


Bunun çok geç bir yorum olduğunu biliyorum, ancak Windows ABI yapıları ve sınıfları farklı şekilde yönettiğinden ve bu nedenle sınıf ve yapı bildirimlerini karıştırmak (ileri) aslında bağlantı sorunlarını kavramaya zorlayabileceğinden, yukarıda belirtilen uyarının haklı olmadığını unutmayın!
MFH

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

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

    2. Boş yapının boyutu 0 bayt w Boş sınıfın boyutu 1 bayttır Yapının varsayılan erişim türü herkese açıktır. Verileri gruplandırmak için genellikle bir yapı kullanılmalıdır.

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

    Kısacası, kural, amacı verileri gruplamak olduğunda yapı kullanmak ve veri soyutlaması ve belki de miras gerektiğinde sınıfları kullanmaktır.

    C ++ 'da yapılar ve sınıflar açıkça atıfta bulunulmadıkça değere göre geçirilir. Diğer dillerde, sınıflar ve yapılar farklı anlambilimlere sahip olabilir - yani. nesneler (sınıf örnekleri) referansla geçirilebilir ve yapılar değere göre geçirilebilir. Not: Bu soru ile ilişkili yorumlar var. Sohbete eklemek için tartışma sayfasına bakın.


3
Msgstr "2. Boş yapının boyutu 0 bayt ve boş sınıfın boyutu 1 bayt". Yanlış. Sadece test ettim g++. Boş Taban Optimizasyonu düşünüyor olabilirsiniz, ancak bu her ikisi için de geçerlidir.
cdunn2001

1
Doğru değil. C ++ 'da boş bir yapının boyutu 1'dir. C' de boş bir yapıya izin verilmez. GCC, derleyici uzantısı olarak C'deki boş yapılara izin verir ve böyle bir yapı 0 büyüklüğüne sahiptir.
Johan Råde 13:14

Bu cevap yanlış. Boyut şeye ek olarak, yapıcı / yıkıcı kısmı da yanlıştır: yapıların yapıcıları ve yıkıcıları gayet iyi olabilir. Aslında, structC ++ 'da tam teşekküllü sınıflar oluşturur.
17'de

1

Diğer cevaplar tarafından ima edilmesine rağmen, açıkça belirtilmemiştir - yapıların kullanıma bağlı olarak C uyumlu olduğu; sınıflar değildir.

Bu, C uyumlu olmasını istediğiniz bir başlık yazıyorsanız, yapıdan başka bir seçeneğiniz olmadığı anlamına gelir (C dünyasında işlevler olamaz; ancak işlev işaretçileri olabilir).


-1

Yapı veya sınıfa ne zaman gidileceğine ilişkin yönergeler için bunu düşünebilirsiniz, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

Type Tür örnekleri küçük ve genellikle kısa ömürlü ise veya genellikle diğer nesnelere gömülmüşse, sınıf yerine bir yapı tanımlayan CONSIDER.

X Aşağıdaki özelliklerin hepsine sahip olmadıkça bir yapıyı tanımlamaktan KAÇININ:

Mantıksal olarak ilkel tiplere (int, double, vb.) Benzer tek bir değeri temsil eder.

16 baytın altında bir örnek boyutuna sahiptir.

Değişmez.

Sık sık kutsanması gerekmeyecek.


Bu, .NET / C # ile ilgilidir, C ++ ile değil.
17'de

-2

Sınıf sadece yazılım mühendisliği bağlamında anlamlıdır. Veri yapıları ve algoritmalar bağlamında, sınıf ve yapı o kadar da farklı değildir. Sınıf üyesine başvurulması gereken herhangi bir kural yoktur.

Sınıfsız tonlarca insanla büyük bir proje geliştirirken, sonunda karmaşık birleştirilmiş kod alabilirsiniz, çünkü herkes istediği işlevleri ve verileri kullanır. sınıf, kod çözme ve yeniden kullanma kodlarını geliştirmek için izin kontrolleri ve doğası gereği sağlar.

Bazı yazılım mühendisliği prensiplerini okursanız, standartların çoğunun sınıf olmadan kolayca uygulanamayacağını göreceksiniz. örneğin: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

BTW, Bir yapı bir bellek yığını ayırdığında ve birkaç değişken içerdiğinde, değer türü değişkenleri, değerlerin yapı tahsis edildiği yere gömüldüğünü gösterir. Buna karşılık, referans tipi değişkeninin değerleri harici olup, yapının tahsis edildiği yere gömülü olan bir işaretçi ile referanstır.


Bu cevap C ++ ile ilgili görünmüyor. C ++ 'da structsınıfları bildirir (izin denetimleri, kalıtım vb. Dahil).
melpomene

-3

Arasındaki fark yapı ve sınıf orada özellikle kompozit veri türü konusunda özel belirteci varsayılan tarafından daha sonra ise C ++ anahtar kelimeler, yani yapı veya birlik sadece veri saklamayı düşündüğü kamu anahtar kelimeler ama sınıf programının gizlenmesini gördüğü özel anahtar kelimedir kodlar veya veriler. Her zaman bazı programcılar veri için yapı ve kod uğruna sınıf kullanır. Daha fazla bilgi için diğer kaynaklara başvurun.


OP zaten structüyelerin varsayılan olarak kamuya açık olduğundan bahsetti ve 2009'dan kabul edilen cevap kalıtımdan bahsediyor. Neden 4 yıl sonra yeni bilgi eklemeyen başka bir cevap yazmalıyım?
17'de

-3

Tüm bu faktörlerden, kavram Sınıfının "Yapılar" dan ziyade gerçek dünya nesnelerini temsil etmek için son derece uygun olduğu sonucuna varılabilir. Çünkü sınıfta kullanılan OOP kavramları, gerçek dünya senaryolarını açıklamada oldukça pratiktir, bu nedenle bunları gerçekle birleştirmek daha kolaydır. Örneğin, varsayılan kalıtım yapılar için herkese açıktır, ancak bu kuralı gerçek dünya için uygularsak çok saçma olur.

Her neyse, gerekçelendirmem gereken şey Sınıf çok daha geniş, gerçek dünyaya uygulanabilir bir kavram iken Yapı zayıf iç organizasyona sahip ilkel bir kavramdır (Yapı OOP kavramlarını takip etmesine rağmen, zayıf bir anlamı vardır)


1
Özel kalıtım nasıl "daha gerçekçi"? Çoğu programlama dili özel miras kavramına bile sahip değildir.
17'de

-3

Oops'ta yapı ve sınıf anahtar kelimesi arasındaki temel fark, yapıda hiçbir genel ve özel üye bildirimi bulunmamasıdır. Ve veri üyesi ve üye işlevi, genel, özel ve korumalı olarak tanımlanabilir.


Bu cevap C ++ ile ilgili görünmüyor. C ++ 'da structsınıfları bildirir ( public/ private/ protected, kalıtım vb. Dahil ).
melpomene

-3

** GÜNCELLEME: ** Lütfen bu yanıtı dikkate almayın. Yapı için değerin başlatılmadığını, ancak sadece 0 olduğunu düşünmedim. Yapı ve sınıf arasında bir başlatma farkı yoktur.


Yapılar ve varsayılan başlatma ile ilgili sınıflar arasında başka bir farklı görüyorum.

struct Foo {
    int a;
};

class Bar {
    int a;
};

class Tester {
    Foo m_Foo = Foo();
    Bar m_Bar = Bar();

public:
    Tester() {}
};

int main() {
    auto myTester = Tester();
}

Bu kodu çalıştırın ve myTester'ı inceleyin. M_Foo için m_Foo.a yapısının 0 olarak başlatıldığını, ancak m_Bar için m_Bar.a sınıfının başlatılmadığını göreceksiniz. Bu nedenle, varsayılan kurucunun struct vs. sınıfı için yaptıklarında bir fark var gibi görünüyor. Bunu Visual Studio ile görüyorum.


1
m_Foo.aBaşlatıldığını nasıl belirlediniz ? Başlatılmamış ve henüz olmuş olsaydı ne olurdu 0?
melpomene

Ahh, ben yapmadım. Benim hatam. Bu yapı ve sınıf arasındaki fark değildir. Başlatma özellikleri aynıdır.
Eric Hill

-4

Yapı ve sınıf arasındaki temel fark, yapıda yalnızca farklı veri türlerinin veri değişkenlerini bildirebilmenizdir, sınıfta veri değişkenlerini, üye işlevlerini bildirebilir ve böylece veri değişkenlerini işlevler aracılığıyla değiştirebilirsiniz.

-> sınıf vs struct içinde bulduğum bir başka kullanışlı şey, bir programda dosyaları uygularken, bir yapının bazı işlemlerini tekrar tekrar yapmak istiyorsanız, her yeni işlem setinde ayrı bir işlev yapmanız ve Yapının nesnesini dosyadan okuduktan sonra üzerinde bazı işlemler yapmak için geçirin. sınıfta iken her zaman gerekli veriler üzerinde bazı işlemler yapan bir işlev yaparsanız ... kolay sadece dosyadan nesne okumak ve işlevi çağırmak zorunda ..

Ama programcıya hangi yolu uygun bulduğuna bağlı ... Bana göre her seferinde sınıfı tercih ediyorum çünkü sadece OOP'ları destekliyor ve neredeyse her dilde uygulanmasının nedeni ve tüm zaman programlamanın harika özelliği; )

Ve bahsetmeyi unuttuğum en unutulmaz fark, sınıfın veri gizlemeyi desteklemesi ve ayrıca yapı yapmazken dahili veri türlerinde gerçekleştirilen işlemleri desteklemesidir!


1
C ++ ' structda üye işlevleri olabilir
chtz

@chtz Teşekkürler ... ben şimdi bu özellik hakkında bilmek lazım .. çok teşekkür ederim .. im sadece bir acemi olarak sizin kadar uzman değil, bu yüzden u çocuklar da tavsiye gerekir :-)
Yug Rawal

ve aslında üye işlevi daha geniş anlamında düşünülmelidir. structkurucuları, üye işlevi ve yıkıcısı olabilir (muhtemelen sanal, muhtemelen özel, korumalı veya herkese açık). Kalıtsal ve kalıtsal olabilirler. yani aslında ... bir sınıfın sahip olabileceği her şey. Tipik bir kural, yapı içinde C ile yapı olarak ilan edeceğiniz şeyi ve özel ve korumalı değişken, sanal fonksiyonlar, ctor ve dtor vb. Ama bu sadece bir kongre, dil tarafından uygulanmıyor
Gian Paolo

-5

Başka bir fark buldum. sınıfta bir kurucu tanımlamazsanız, derleyici bir kurucu tanımlar. ancak bir kurucuda bir kurucu tanımlamazsanız, derleyici de kurucu tanımlamaz. bu yüzden bazı durumlarda gerçekten bir kurucuya ihtiyacımız yok, yapı daha iyi bir seçimdir (performans ipucu). ve kötü İngilizcem için üzgünüm.


4
Bu doğru değil. structAnahtar kelime ile tanımlanan bir sınıf ile bu konuda anahtar kelime ile tanımlanan bir sınıf arasında fark yoktur class.
ymett

bir kurucu ile bir yapı kullandığınızda, ben bir kurucu ile bir sınıf daha iyi bir hız olsun.
Ali

@Ali Hayır, bilmiyorsun.
Yörüngedeki Hafiflik Yarışları

-5

Sınıflar Referans türleridir ve Yapılar Değer türleridir.
Sınıfların referans türleri olduğunu söylediğimde,
temelde bir örnek değişkenlerinin adresini içereceklerdir.

Örneğin:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

Ana yöntemde,
bu sınıf için bellek ayıran
ve bunun temel adresini MyClass türü değişkenine (_myClassObject2) depolayan yeni işleç kullanarak bu sınıfın bir örneğini oluşturabilirim .

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

Yukarıdaki programda, MyClass _myClassObject2 = _myClassObject1; komutu MyClass türünün her iki değişkeninin de

  1. myClassObject1
  2. myClassObject2

ve aynı bellek konumunu gösterecektir.
Temel olarak aynı bellek konumunu aynı türdeki başka bir değişkene atar.

Bu nedenle, her
ikisi de aynı bellek konumuna işaret ettiğinden, MyClass türündeki nesnelerden herhangi birinde yaptığımız herhangi bir değişiklik başka bir etki üzerinde etkili olacaktır .

"_myClassObject1.DataMember = 10;" bu satırda nesnenin veri üyeleri 10 değerini içerir.
"_myClassObject2.DataMember = 20;" bu satırda hem nesnenin veri üyesi 20 değerini içerir.
Sonunda, bir nesnenin veri üyelerine işaretçilerle erişiyoruz.

Sınıfların aksine, yapılar değer tipleridir. Örneğin:

Structure MyStructure
{
    Public Int DataMember;  //By default, accessibility of Structure data 
                            //members will be private. So I am making it as 
                            //Public which can be accessed out side of the structure.
}

Static Public void Main (string[] arg)
{
    MyStructure _myStructObject1 = new MyStructure();
    _myStructObject1.DataMember = 10;

    MyStructure _myStructObject2 = _myStructObject1;
    _myStructObject2.DataMember = 20;
}

Yukarıdaki programda,
MyStructure türünün nesnesini yeni operatör kullanarak örneklemek ve
adresi MyStructure türündeki _myStructObject değişkenine depolamak ve
"_myStructObject1.DataMember = 10" kullanarak yapının veri üyesine 10 değeri atamak.

Sonraki satırda,
MyStructure türünde başka bir değişken _myStructObject2 bildiriyorum ve buna _myStructObject1 ataıyorum.
Burada .NET C # derleyicisi _myStructureObject1 nesnesinin başka bir kopyasını oluşturur ve
bu bellek konumunu _myStructObject2 MyStructure değişkenine atar.

Yani _myStructObject1 üzerinde yaptığımız herhangi bir değişiklik, MyStructrue türündeki başka bir _myStructObject2 değişkeni üzerinde asla bir etkiye sahip olmayacaktır.
Bu yüzden Yapıların değer türleri olduğunu söylüyoruz.

Sınıf için derhal Base sınıfı Object ve Object için derhal Base sınıfı, Object'ten devralınan ValueType'tır.
Sınıflar Kalıtım'ı desteklerken Yapılar desteklemez.

Bunu nasıl söylüyoruz?
Bunun arkasındaki sebep nedir?
Cevap Sınıflar.

Soyut, mühürlü, statik ve kısmi olabilir ve Özel, Korumalı ve korumalı dahili olamaz.


4
Sanırım bu c # sorusuna cevap vermeye çalışıyor? Soru c ++ ile ilgilidir ve bu cevabı yanlış yapar, değil mi?
smw

@smw kesinlikle, onun örnek kodunu C # yazdı ve buraya C ++ structve arasında parametre geçişinde bir fark olmadığını kontrol etmek için geldi class. Burada kimse bundan veya tüm web'den bahsetmedi. Yani bunun C ++ için de geçerli olduğunu düşünmüyorum.
John

Bu bile geçerli C # kodu değil - anahtar kelimelerin hepsi yanlış. "Herkese açık", "Statik", "Int" ve "Sınıf" büyük harfle yazılmamalı ve "Yapı" değil "yapı" olmalıdır. Açıklama çoğunlukla C # için doğrudur (yapılar hala diğer yapıları değil, arayüzleri devralabilir), ancak C ++ ile ilgili olduğu için soruyu cevaplamaz ...
Darrel Hoffman

2
Bu cevap tam bir saçmalıktır. Kod örnekleri için garip bir Visual Basic ve C # karışımı kullanır ve tüm "Sınıflar başvuru türleri ve yapıları değerler türleri" ... şey yalnızca .NET (yani C #) için C ++ için geçerlidir. Yanlış odadasınız, ahbap.
Ait olduğunuz yer

Ancak bu cevap , aynı şeyin C (++) için geçerli olduğunu, yapıların değer türleri gibi kullanıldığını gösterir. int a = 3; int b = a;ve benzeriMyStruct a=MyStruct("data"); MyStruct b = a;
luckydonald

-8

Yapı ve sınıf arasında 3 temel fark vardır

1St- bellek, yığın belleğindeki sınıf için sadece tekrarlama için ayrılmış ve gerçek bellek yığın belleğinde ayrılmış olsun, yığın bellekteki (programlama diline yakın) yapı için ayrılmıştır.

2Nd - Varsayılan yapı olarak, sınıfın özel muamele görüp görmediği herkese açık olarak ele alınır.

3Rd- kodu yapıda yeniden kullanamaz, ancak sınıfta aynı kodu miras olarak adlandırılan birçok zamanda tekrar kullanabiliriz


2
C ++ yapıları kalıtım ve soyut yöntemleri destekler. Yapı ve sınıf aynı şekilde tahsis edilir. Sınıfı "yeni" ile başlatılmasalar bile öbek üzerinde tahsis etmek gömülü sistemler için bir anlam ifade etmez.
JCMS

2
# 1 de yanlış. Yığın, bu türden bir şeyi yerel değişken olarak bildirdiğinizde ve yığın "yeni" işleci kullandığınızda kullanılır.
15'de 0:23
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.