C / C ++ Struct ve Sınıf


108

C ++ sınıfımı bitirdikten sonra, yapıların / sınıfların birkaç küçük fark dışında neredeyse aynı olduğunu gördüm.

Daha önce hiç C'de programlamadım; ama yapıları olduğunu biliyorum. C'de diğer yapıları devralmak ve bir genel / özel değiştirici ayarlamak mümkün müdür?

Eğer bunu normal C ile yapabiliyorsanız, neden dünyada C ++ 'ya ihtiyacımız var? Sınıfları bir yapıdan farklı kılan nedir?

c++  class  struct 


Yanıtlar:


147

C ++ 'da yapılar ve sınıflar hemen hemen aynıdır; tek fark, sınıflardaki erişim değiştiricilerin (üye değişkenler, yöntemler ve temel sınıflar için) varsayılan olarak özel olarak ayarlanması durumunda, yapılardaki erişim değiştiricilerin varsayılan olarak public olarak ayarlanmasıdır.

Bununla birlikte, C'de , yapı yalnızca (genel) verilerin toplu bir koleksiyonudur ve başka hiçbir sınıfa benzer özelliği yoktur: yöntem yok, yapıcı yok, temel sınıf yok, vb. C ++ anahtar kelimeyi miras almasına rağmen, anlambilimini genişletti. (Bununla birlikte, bu, şeylerin yapılarda genel olarak varsayılan olmasının nedenidir - C yapısı gibi yazılmış bir yapı, bir yapı gibi davranır.)

C'de bazı OOP'yi taklit etmek mümkün olsa da - örneğin, ilk parametresi olarak bir yapıya işaretçi alan işlevleri tanımlamak veya zaman zaman aynı ilk birkaç alana sahip yapıları "alt / üst sınıflar" olmaya zorlamak - her zaman bir çeşittir cıvatalı ve aslında dilin bir parçası değil.


OOP'tan potansiyel .Net çalışanları, bunu bu şekilde tanımladılar ✓ CONSIDER türün örnekleri küçükse ve genellikle kısa ömürlü ise veya genellikle başka nesnelere gömülmüşse, bir sınıf yerine bir yapı tanımlamayı düşünün. X Aşağıdaki özelliklerin tümüne sahip olmadıkça bir yapıyı tanımlamaktan KAÇININ: 1. İlkel türlere (int, double, vb.) Benzer şekilde mantıksal olarak tek bir değeri temsil eder. 2. 16 baytın altında bir örnek boyutuna sahiptir. 3. Değişmezdir.
Abhijeet

5
@Abhijeet Bu, C # 'da yapılar ve sınıflar arasındaki ayrımdır, ancak bu sadece C ++ ile ilgisiz ve hatta C ile daha da ilgisi yoktur. C #' da, sınıflar ve yapılar aslında farklıdır; C ++ 'da böyle değildir ve C yalnızca OO'suz yapılara sahiptir.
Antal Spector-Zabusky

C ++ yapısında aynı C semantikini korumak daha iyi olmaz mıydı? ve bir "struct in a c ++ yolu" kullanılması gerektiğinde, sadece bir sınıf kullanın C ile karşılaştırıldığında C ++ 'da "artırılmış" bir yapıya sahip olmanın avantajını hiçbir zaman elde edemedim. C de tasarlandığı gibi hala yapı kullanmayı seviyorum, aksi takdirde izin verilen bazı istisnalar dışında bir sınıf kullanın.
Raffaello

15

Bunun dışında varsayılan erişimdeki (genel / özel) farklılıklar arasında bir fark yoktur.

Bununla birlikte, C ve C ++ 'da kodlayan bazı mağazalar, hangilerinin C ve C ++' da (yapı) kullanılabileceğini ve hangilerinin yalnızca C ++ (sınıf) olduğunu belirtmek için "sınıf / yapı" kullanır. Diğer bir deyişle, bu tarzda tüm yapılar C ve C ++ ile çalışmalıdır. Uzun zaman önce, C ++ 'nın hala "Sınıflarla C" olarak bilinirken, ilk etapta bir fark olmasının nedeni budur.

C sendikalarının C ++ ile çalıştığını, ancak bunun tersi olmadığını unutmayın. Örneğin

union WorksWithCppOnly{
    WorksWithCppOnly():a(0){}
    friend class FloatAccessor;
    int a;
private:
    float b;
};

Ve aynı şekilde

typedef union friend{
    int a;
    float b;
} class;

sadece C'de çalışır


9
Sizin c kodunda cpp anahtar kelimeleri kullanma ve daha sonra uyumlu CPP değildir iddia oldukça aptaldır
Dani

7

Mevcut cevaplara bir şeyler ekleyeceğim çünkü modern C ++ artık bir şey ve bu gibi sorulara yardımcı olmak için resmi Temel Yönergeler oluşturuldu.

İşte yönergelerden alakalı bir bölüm:

C.2: Sınıfın değişmezliği varsa sınıfı kullanın; veri üyeleri bağımsız olarak değişiklik gösterebilirse struct kullanın

Bir değişmez, bir nesnenin üyeleri için, bir yapıcının genel üye işlevlerinin üstlenmesi için kurması gereken mantıksal bir koşuldur. Değişmez oluşturulduktan sonra (tipik olarak bir kurucu tarafından), nesne için her üye işlev çağrılabilir. Bir değişmez, gayri resmi olarak (örneğin bir yorumda) veya Beklentiler kullanılarak daha resmi olarak ifade edilebilir.

Tüm veri üyeleri birbirinden bağımsız olarak değişebiliyorsa, değişmezlik mümkün değildir.

Bir sınıfın herhangi bir özel verisi varsa, kullanıcı bir yapıcı kullanmadan bir nesneyi tamamen başlatamaz. Bu nedenle, sınıf tanımlayıcı bir kurucu sağlayacaktır ve anlamını belirtmesi gerekir. Bu, tanımlayıcının bir değişmezi tanımlaması gerektiği anlamına gelir.

Uygulama

Tüm verileri özel ve genel üyeleri olan sınıfları içeren yapıları arayın.

Verilen kod örnekleri:

struct Pair {  // the members can vary independently
    string name;
    int volume;
};

// but

class Date {
public:
    // validate that {yy, mm, dd} is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
};

Classes, örneğin birbirlerinden türetilmiş veya birbiriyle ilişkili üyeler için iyi çalışır. Ayrıca, örnekleme üzerine akıl sağlığı kontrolüne de yardımcı olabilirler. StructGerçekten özel bir şeyin olmadığı, ancak üyelerin mantıksal olarak bir araya getirilmesinin mantıklı olduğu "veri torbalarına" sahip olmak için iyi çalışıyorlar.

Buradan, classkapsüllemeyi ve diğer ilgili kodlama kavramlarını desteklemek için var olduğu, ancak structbunlar için pek yararlı olmadığı mantıklıdır .


Diğer bir husus taşınabilirliktir. structs en taşınabilir olanlardır. C veya C ++ tarafından veya ileri geri kullanılabilirler. structÖrneğin , modül kullanılarak Python'da paketten çıkarılabilirler . Proje öncelik diğer diller, arabirimler veya sistemleri ile uyumlu olma durumunda, tercih structüzerinde class. Kesinlikle program iç işleri için tercih edin class.
Dave

6

C'de üye işlevler tanımlamak veya yapıları birbirinden türetmek mümkün değildir.

Ayrıca, C ++ yalnızca C + "yapıları türetmek" değildir. Şablonlar, referanslar, kullanıcı tanımlı ad alanları ve operatör aşırı yüklemelerinin tümü C'de mevcut değildir.


C'de şablonların vb power. Olmadığını biliyorum, ancak C'deki yapıların farkında değildim . O halde C ++, yapıları yalnızca C ile geriye doğru uyumlu olacak şekilde kullanıyor?

4
Sadece geriye dönük uyumluluk için mi? Pratik bir temelde, muhtemelen bununla ilgili bir şeyler vardır, ancak ayrım, bir niyet sinyali olabilir: Ben kullandığım yerde struct, büyük ölçüde pasif POD türü bir şeyi kastediyorum.
dmckee --- eski moderatör yavru kedi

@dmckee: Değeri ne olursa olsun, çoğu STL functoru (yani std::less) sınıflar olarak değil yapılar olarak tanımlanır.
Billy ONeal

1
C ++, C ile tamamen uyumlu değildir. Struct anahtar kelimesinin C geliştiricileri için bir uyum olduğunu söyleyebilirsiniz. Verileri sıralı bir şekilde tutan ancak kendileri (çok) mantık sağlamayan sınıflar için struct anahtar sözcüğünü seviyorum.
ypnos

@ypnos: Son yorumuma bakın. İkisi arasındaki tek fark, birinin üyelerinin varsayılan genel, diğerinin varsayılan özel olmasıdır.
Billy ONeal

3

C ++ 'da bir başka fark, herhangi bir erişim belirticisi olmadan yapıdan bir sınıfı miras aldığınızda, sınıf durumunda olduğu gibi özel miras olduğu genel miras haline gelir.


1

C ++, yapıları öncelikle 1) C ile geriye dönük uyumluluk ve 2) POD türleri için kullanır. C yapılarının yöntemleri, kalıtımı veya görünürlüğü yoktur.


2
Değeri ne olursa olsun, çoğu STL functoru (yani std::less) sınıflar olarak değil yapılar olarak tanımlanır.
Billy ONeal

3
C ++ yapılarının yöntemleri, kalıtımı ve görünürlüğü olduğunu unutmayın.
robertwb

c struct işlev göstericisini tür olarak (* adres) (parametreler) içerebilir;
hatası
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.