C ++の構造体とクラスの違いは何ですか?


439

この質問は、C#/。Netのコンテキストですでに尋ねられました

次に、C ++での構造体とクラスの違いを学びたいと思います。OO設計で技術的な違いとどちらか一方を選択する理由について説明してください。

明らかな違いから始めましょう:

  • public:またはを指定しない場合private:、構造体のメンバーはデフォルトでパブリックになります。クラスのメンバーはデフォルトでプライベートです。

C ++仕様のあいまいなコーナーには他にも違いがあると思います。


6
このリンクは違いをよくまとめています。
sjsam 2015年

1
では、なぜみんながstructを使用してツリーを構築するのでしょうか。違いはそれほどないようです。ところで、それは素晴らしいウェブサイトです。@ sjsam
JW.ZG

1
structCとC ++ の違いをお探しですか?こちらをご覧ください
Marc.2377

@ JW.ZG「すべて」の人がするわけではありません!それを行う人々は、単にstructC ++を好むか、C ++の意味を理解していません。;)しかし、class代わりにキーワードを使用できない理由はありません。
、オービットのライトネスレース

回答:


465

クラスと構造体の間のトリッキーな2番目の違いを忘れます。

標準をクーズします(C ++ 98からC ++ 11の§11.2.2):

非存在下でアクセス指定子 派生クラスが宣言されたときに、基本クラスのため、公衆が想定される 構造体を、専用のクラスが宣言されたときに想定されるクラス

そして、完全を期すために、クラスと構造体の間で広く知られている違いは、(11.2)で定義されています。

キーワードで定義されたクラスのメンバークラスがあり、民間デフォルトで。キーワードで定義されたクラスのメンバー構造体または共用体が あり、公共デフォルトで。

追加の違い:キーワードclassはテンプレートパラメータの宣言に使用できますが、structキーワードはそのように使用できません。


22
これは実際には2番目の違いではありません。問題が違いを不完全に述べているだけです。を使用する場合、すべてのサブオブジェクトはデフォルトでプライベートでありclass、デフォルトでとともにパブリックstructであり、両方ともクラスタイプを定義します。
Ben Voigt、2011

10
要点を逃したと思います、ベン。構造体ではパブリックであり、クラスではプライベートである継承です。これは非常に重要な違いであり、実際のメンバーアクセスとはまったく無関係です。たとえば、言語はそれ以外の場合はそれを非常にうまく定義している可能性があります。たとえば、両方ともデフォルトでパブリックに継承され、非常に異なる影響が得られます。
Assaf Lavie、2011

104
実際には、実際のトリッキーstructとは、class後者の代わりに使用することができることであるtypenameテンプレートパラメータを宣言するために、前者ができるがありません。:)
sbi

21
@MrUniverse:これはまったく間違っています。(これを規約に使用している学校がありますが、それは構文的に強制されていません。)
sbi 2013年

3
@sbi「構造体とクラスの間に本当のトリッキーな違い」 -かわいい、しかし問題は、の違いについてである構造体やクラス、しないキーワードを使用できる場所の違いについて。
ジムバルター、2015年

161

引用C ++よくある質問を

[7.8]キーワードstructとclassの違いは何ですか?

構造体のメンバーと基本クラスはデフォルトでパブリックですが、クラスではデフォルトでプライベートになります。注:デフォルトに依存するのではなく、基本クラスを明示的にパブリック、プライベート、または保護する必要があります。

その他の点では、構造体とクラスは機能的に同等です。

さて、そのきしむクリーンなテクノの話は十分です。感情的には、ほとんどの開発者はクラスと構造体を強く区別します。構造体は、カプセル化または機能の方法がほとんどない、開いたビットの山のように感じるだけです。クラスは、インテリジェントサービス、強力なカプセル化バリア、明確に定義されたインターフェイスを備えた、社会の生きた責任あるメンバーのように感じます。これはほとんどの人がすでに持っている意味合いなので、メソッドがほとんどなく、パブリックデータがあるクラスがある場合は、おそらくstructキーワードを使用する必要があります(適切に設計されたシステムに存在するものなど)。それ以外の場合は、おそらくクラスを使用する必要があります。キーワード。


123

C ++の起源とCとの互換性を覚えておく価値があります。

Cには構造体があり、カプセル化の概念がないため、すべてがパブリックです。

オブジェクト指向のアプローチを採用する場合、デフォルトでパブリックであることは一般に悪い考えと見なされます。そのため、OOPをネイティブで支援するCの形式を作成する場合(CでOOを実行できますが、それはあなたを助けません)、 C ++(元々は「C With Classes」)のアイデアでは、デフォルトでメンバーをプライベートにすることは理にかなっています。

一方、Stroustrupがstructそのメンバーをデフォルトで非公開にするようにセマンティクスを変更した場合、互換性が失われます(標準が発散するほど頻繁には当てはまりませんが、すべての有効なCプログラムは有効なC ++プログラムでもあり、これはC ++に足場を置くことに大きな影響を与えました)。

そのため、新しいキーワードclassが構造体とまったく同じように導入されましたが、デフォルトではプライベートです。

C ++が最初から来ていて、履歴がない場合は、おそらくそのようなキーワードは1つだけです。それはおそらくそれが作った影響を与えなかっただろう。

一般に、人々はCでの構造体の使用方法のようなことをしているときに、構造体を使用する傾向があります。パブリックメンバー、コンストラクターなし(ユニオンにない限り、クラスと同じようにコンストラクターを構造体に含めることできます、人々はそうしない傾向があります)、仮想メソッドなどはありません。言語は、マシンに命令するためにコードを読んでいる人(または、アセンブリと生のVMオペコードに固執する人)は、それに固執することをお勧めします。


また、クラスと構造を基本的に異なるものにするよりも、内部でクラスと構造を同じように機能させるほうがおそらく簡単だったことにも注目する価値があります。振り返ってみると、たとえば、構造体として宣言されたものはすべてPODS(つまり、構造体が仮想メンバー、重要なデフォルトコンストラクターまたはデストラクタを持つことを禁止する)でなければならないことを指定することには利点があるかもしれませんが、そのようなことは私の知る限りではありませんこれまで、C ++標準や実装で必要とされていました。
スーパーキャット2013

1
@supercatそれが非OO言語で書かれたプログラムの膨大なレパートリーが有効なプログラムであるOO言語であるという事実は、コンセプトを前面に押し出し、より純粋にOO言語よりもそこに登場するようです。 (もちろん、実際には標準で定義されています)。初期のC ++の歴史は間違いなく多くのことを説明しています。Stroustrupの「C ++のデザインと進化」は興味深い読み物です。
Jon Hanna

1
私は「OOPっぽい」ではないこと、すべてを感じる人々の間の宗教戦争を知覚、あるべき、とOOPのように見なされるべきだと思う人ツールではなくツール。C ++は確かに後者の哲学を採用しているようですが、それ以前の言語についてはあまり知りません。私自身の哲学は、オブジェクトが必要な場合はオブジェクトを使用し、関連するが独立した変数の集約が必要な場合はそれを使用することです。C ++はこれらの種類の構文的な区別を行わず、.NETはその区別を曖昧にしようとしますが、私がDについて知っていることはほとんどありません...
supercat

1
... C ++や.NETよりも認識しやすいことを示唆しています。変数の集合体は正確にOOPishではありませんが、それはそれらが有用なときに採用されるべきではないという意味ではありません。
スーパーキャット2013

3
「Cには構造体があり、カプセル化の概念がないため、すべてがパブリックです。」に同意しません。-File struct内の定義を非表示にして、*.c他の翻訳ユニットにポインターでのみ使用させることができます。そのため、他の翻訳ユニットは内に何があるのか​​さえわからないため、さらに強力なカプセル化が得られますstruct
12431234123412341234123

32

クラスのメンバーはデフォルトでプライベートです。Structのメンバーはデフォルトでパブリックです。それ以外には違いはありません。こちらの質問もご覧ください。


15
メンバーだけでなく、継承を含むすべてのアクセス権。
Nemanja Trifunovic

4
さて、他の違いはセマンティクスです。多くの人々への構造体は、それらがCから残り物として「データ構造」を思わせる
クリスKumler

3
@KrisKumler:これらは「セマンティクス」ではありません。それらは個人的な感情です。どちらstructclass宣言したクラスを同じセマンティクス(定義体の解析単位の解釈にもかかわらず)で。
Orbitのライトネスレース2016年

28

C ++プログラミング言語の Stroustrupによると:

どちらのスタイルを使うかは、状況や好みによって異なります。私は通常、structすべてのデータを公開するクラスに使用することを好みます。私はそのようなクラスを「まったく適切な型ではなく、単なるデータ構造」と考えています。

機能的には、パブリック/プライベート以外に違いはありません


32
何が違う?説明してください。
crashmstr 2009年

10

STRUCTは、構造の仕様に従ってメモリの特定のチャンクを分割する抽象データ型の一種です。構造体はファイルに逐語的に書き込むことができるため、構造体はファイルのシリアル化/逆シリアル化で特に役立ちます。(つまり、構造体へのポインタを取得し、SIZEマクロを使用してコピーするバイト数を計算してから、データを構造体の内外に移動します。)

クラスは、情報を確実に隠蔽するための異なるタイプの抽象データ型です。内部的には、さまざまな操作、メソッド、一時変数、状態変数があります。クラスを使用したいすべてのコードに一貫したAPIを提供するためにすべて使用されます。

実際、構造体はデータに関するものであり、クラスはコードに関するものです。

ただし、これらは単なる抽象化であることを理解する必要があります。クラスのように見える構造体や、構造体のように見えるクラスを作成することは完全に可能です。実際、最も初期のC ++コンパイラは、C ++コードをCに変換する単なるプリコンパイラでした。したがって、これらの抽象化は論理的思考にとってのメリットであり、必ずしもコンピュータ自体の資産ではありません。

それぞれが異なるタイプの抽象化であるという事実を超えて、クラスはCコード命名パズルのソリューションを提供します。同じ名前で複数の関数を公開することはできないため、開発者は_()のパターンに従っていました。たとえば、mathlibextreme_max()です。APIをクラスにグループ化することにより、類似の関数(ここではそれらを「メソッド」と呼びます)をグループ化して、他のクラスのメソッドの名前付けから保護できます。これにより、プログラマーはコードを適切に整理し、コードの再利用を増やすことができます。理論的には、少なくとも。


1
これは、構造体とクラスについて最も明白ではないことです。「構造はデータについて、クラスはコードについて」は、「構造はデータについてであり、クラスはデータ、セキュリティ、およびこのデータで実行される操作についてである」と言い換えることができます
Arun Aravind

3
C ++で構造体を作成することはできません。継承されたstructキーワードを使用してクラスを作成することのみが可能です。
オービットのライトネスレース

1
この答えはC ++に関するものではないようです。C ++では、structクラス(public/ private/ protected、継承など)を宣言します。
melpomene 2017年

構造体はどのように抽象的ですか?生の構造体をファイルに書き込むと、Cでも問題が発生します(通常の問題には、パディング、エンディアン、異なるワードサイズなどがあります)。SIZEあなたが話しているこのマクロは何ですか?
melpomene 2017年

10

1)クラスのメンバーはデフォルトでプライベートで、構造体のメンバーはデフォルトでパブリックです。

たとえば、プログラム1はコンパイルに失敗し、プログラム2は正常に動作します。

// 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)クラス/構造体から構造体を派生する場合、基本クラス/構造体のデフォルトのアクセス指定子はパブリックです。また、クラスを派生する場合、デフォルトのアクセス指定子はプライベートです。

たとえば、プログラム3はコンパイルに失敗し、プログラム4は正常に動作します。

// 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;
}

エキスパートが言及したコード例3〜7を削除しました
Suraj K Thomas

8

他の唯一の違いは、クラスと構造体のデフォルトの継承です。当然ながら、それぞれプライベートとパブリックです。


5
  1. 構造体のメンバーはデフォルトでパブリックであり、クラスのメンバーはデフォルトでプライベートです。
  2. 別の構造またはクラスからの構造のデフォルトの継承はパブリックです。別の構造またはクラスからのクラスのデフォルトの継承はプライベートです。
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;
}

これはVS2005にあります。


_tmain標準C ++ではありません。
melpomene 2017年

4

仕様にはありません。主な違いは、プログラマが2年間でコードを読んだときの期待にあります。多くの場合、構造体はPODと見なされます。構造体は、オブジェクトの定義以外の目的で型を定義するときに、テンプレートのメタプログラミングでも使用されます。


4

もう1つ注意すべき点として、クラスを使用する構造を持つレガシーアプリを更新した場合、次の問題が発生する可能性があります。

古いコードには構造体があり、コードは整理され、これらはクラスに変更されました。次に、1つまたは2つの仮想関数が、更新された新しいクラスに追加されました。

仮想関数がクラスにある場合、コンパイラーは内部でクラスデータへのポインターを追加して、関数を指すようにします。

これが古いレガシーコードを破壊する方法は、古いコードのどこかで構造体がmemfillを使用してクリアされ、すべてがゼロにクリアされた場合、余分なポインタデータも同様に踏みにじられることになります。


1
memfillを使用して構造体をクリアするコードには、おそらく他の攻撃的な癖があります。注意してください。
David Thornley、

@DavidThornley:Cではデータ構造を消去または初期化するためにゼロフィルを使用するのが標準です。混合言語プロジェクトでは、C部分のコードがcallocを優先して回避することは期待できませんnew。できることは、コードのC部分で使用されるすべての構造が実際にPODSであることを確認することです。
スーパーキャット2013

4
  1. キーワードで定義されたクラスのメンバーはclassあるprivateデフォルトで。キーワードstruct(またはunion)で定義されたクラスのメンバーは、publicデフォルトです。

  2. 基底クラスのアクセス指定子の非存在下で、public場合に想定される派生クラスが宣言されるstructprivate、クラスが宣言された場合に想定されますclass

  3. は宣言できますが、は宣言できenum classませんenum struct

  4. 使用できますtemplate<class T>が使用できませんtemplate<struct T>

また、C ++標準では、型をとして前方宣言してから、型を宣言structするclassときに使用でき、その逆も可能です。また、std::is_class<Y>::valueあるtrueYがあることのためstructclass、しかしであるfalseためenum class


素敵な答えは、私はとの差)が0クリアな紛れもないのですけれどもstructおよびclassC ++ではないデータ型のキーワードとの差(またはいくつかのより良い代替手段です;)
idclev 463035818

@ formerlyknownas_463035818:しかし、それをstd::is_class<Y>::valueカバーしていると思いませんか?
バトシェバ

ええ、それはもっと目立つかもしれないと思っただけです。
idclev 463035818

気にしないでください、あなたの答えはそのまま完璧です、私は別のものを書きました、もう1つ持っていても害はありません
idclev 463035818

4

違いclassとはstruct、キーワードの間ではなく、データの種類の違いです。この二つ

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

どちらもクラス型を定義します。このコンテキストでのキーワードの違いは、デフォルトのアクセスが異なることです。

  • foo::xパブリックであり、パブリックにfoo_base継承されます
  • bar::xプライベートであり、プライベートにbar_base継承されます


2

それは単なる慣習です。単純なデータを保持するために構造体を作成できますが、後でメンバー関数とコンストラクターを追加して時間を進化させます。一方、public以外のものを見るのは珍しい:構造体内のアクセス。


2

ISO IEC 14882-2003

9クラス

§3

構造はclass-keyで 定義されたクラスstructです。そのメンバーと基本クラス(10節)はデフォルトでパブリックです(11節)。


2

もう1つの主な違いは、テンプレートに関してです。私の知る限りでは、構造体ではなくテンプレートを定義するときにクラスを使用できます。

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

1
構造を一般化された型として使用できないことを強調するつもりなら、それは間違いです。そしてstruct、慣例だけでは許可されていません(classここでは別の意味で使用されているキーワードのほうがいいと思います。テンプレートパラメータに「クラス」または「タイプ名」を使用するを参照してください)。
dma_k

キーワードは許可されていませんが、定義したクラスを問題なく渡すことができますstruct。単にそれを試してください。struct T{}; template <typename T> void foo() {} foo<T>();
軌道の軽さのレース

1

他の回答では、プライベート/パブリックのデフォルトについて言及しています(ただし、構造体はクラスであることに注意してください。これらは2つの異なるアイテムではなく、同じアイテムを定義する2つの方法にすぎません)。

特に興味深いのは、(特に、管理者が「アンマネージド」C ++について言及しているため、MSVC ++を使用している可能性が高いため)、特定の状況下でクラスが宣言classされて定義されているstruct場合(またはおそらく逆の場合)、Visual C ++が文句を言うことです。)、それは完全に合法であると規格は述べていますが


私はそれが非常に遅いコメントであることを知っていますが、Windows ABIが構造体とクラスを異なる方法でマングルするため、前述の警告にはメリットがないわけではないことに注意してください。
MFH 2018

1
  • 。クラスでは、すべてのメンバーはデフォルトでプライベートですが、構造体ではメンバーはデフォルトでパブリックです。

    1. 構造体にはコンストラクタやデストラクタのような用語はありませんが、提供しない場合、クラスコンパイラはデフォルトを作成します。

    2. Sizeof空のクラスは1バイトなので、Sizeof空の構造は0バイトです。構造体のデフォルトのアクセスタイプはpublicです。通常、データをグループ化するには構造体を使用する必要があります。

    クラスのデフォルトアクセスタイプはプライベートであり、継承のデフォルトモードはプライベートです。クラスは、データとそのデータを操作するメソッドをグループ化するために使用する必要があります。

    つまり、規則は、データをグループ化することを目的とする場合はstructを使用し、データの抽象化とおそらく継承が必要な場合はクラスを使用することです。

    C ++では、明示的に逆参照されない限り、構造とクラスは値で渡されます。他の言語では、クラスと構造は異なるセマンティクスを持つ可能性があります。オブジェクト(クラスのインスタンス)は参照によって渡され、構造体は値によって渡されます。注:この質問に関連するコメントがあります。会話に追加するには、ディスカッションページを参照してください。


3
「2. Sizeof空のクラスは1バイトなので、Sizeof空の構造は0バイトです。」いいえ。でテストしたところg++です。空のベースの最適化を考えているかもしれませんが、それは両方に当てはまります。
cdunn2001、2013

1
違います。C ++では、空の構造体のサイズは1です。Cでは、空の構造体は許可されません。GCCコンパイラの拡張としてCに空の構造体を可能にし、そのような構造体は、サイズ0有する
ヨハンラド

この答えは間違っています。サイズの問題に加えて、コンストラクタ/デストラクタ部分も不正確です。構造体は、コンストラクタとデストラクタを適切に持つことができます。実際、structC ++で本格的なクラスを作成します。
melpomene

1

他の答えによって暗示されていますが、明示的には言及されていません-その構造体は、使用法に応じてC互換です。クラスはそうではありません。

つまり、C互換にしたいヘッダーを記述している場合、構造体(Cの世界では関数を使用できませんが、関数ポインターを使用できます)以外のオプションはありません。


-1

構造体またはクラスにアクセスするタイミングに関するガイドラインとして、これを検討する場合があります(https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx)

√タイプのインスタンスが小さく、一般に短命であるか、一般に他のオブジェクトに埋め込まれている場合は、クラスの代わりに構造体を定義することを検討してください。

Xが構造体を定義するのを避けるために、型が次のすべての特性を備えている場合を除きます。

プリミティブ型(int、doubleなど)と同様に、論理的に単一の値を表します。

インスタンスサイズは16バイト未満です。

それは不変です。

頻繁にボックス化する必要はありません。


これはC ++ではなく.NET / C#に関するものです。
メルポメン2017年

-2

クラスは、ソフトウェアエンジニアリングのコンテキストでのみ意味があります。データ構造とアルゴリズムのコンテキストでは、クラスと構造はそれほど異なりません。クラスのメンバーを参照する必要があるという制限はありません。

クラスを持たないたくさんの人で大規模なプロジェクトを開発するとき、誰もがどんな関数やデータも使いたいので、やっと複雑な結合コードを得るかもしれません。クラスは、権限の制御と固有のものを提供して、コードの分離と再利用を強化します。

ソフトウェアエンジニアリングの原則を読むと、ほとんどの標準がクラスなしでは簡単に実装できないことがわかります。例:http : //en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

ところで、構造体がメモリのクランチを割り当て、いくつかの変数を含む場合、値型変数は、値が構造体が割り当てられている場所に埋め込まれていることを示します。対照的に、参照型変数の値は外部であり、構造体が割り当てられている場所にも埋め込まれているポインターによって参照されます。


この答えはC ++に関するものではないようです。C ++では、structクラスを宣言します(許可制御、継承などを含む)。
メルポメン2017年

-3

C ++のstructキーワードとclassキーワードの違いは、特定の複合データ型に特定の指定子がない場合、デフォルトではstructまたはunionはデータの非表示のみを考慮するpublicキーワードですが、classはプログラムの非表示を考慮するプライベートキーワードです。コードまたはデータ。常に一部のプログラマーは、データのために構造体を使用し、コードのためにクラスを使用します。詳細については、他のソースに連絡してください。


OPは、structメンバーはデフォルトでパブリックであることをすでに述べており、2009年から受け入れられた回答は継承について言及しています。4年後に新しい情報を追加しない別の回答を書くのはなぜですか?
melpomene 2017年

-3

これらすべての要因の中で、コンセプトクラスは「構造」ではなく、現実世界のオブジェクトを表すのに非常に適していると結論付けることができます。たとえば、構造体のデフォルトの継承はパブリックですが、このルールを現実の世界に適用すると、ばかげています。しかし、クラスのデフォルトの継承は、より現実的なプライベートです。

とにかく、私が正当化する必要があるのは、クラスははるかに広く現実的な適用可能な概念であるのに対し、構造は内部組織が不十分な原始的な概念です(Eventhough構造体はOOP概念に従っていますが、意味がありません)。


1
プライベート継承はどのように「より現実的」ですか?ほとんどのプログラミング言語には、プライベート継承の概念さえありません。
メルポメン2017年

-3

oopsの構造とクラスキーワードの主な違いは、構造にパブリックおよびプライベートメンバー宣言が存在しないことです。データメンバーとメンバー関数は、パブリック、プライベート、および保護として定義できます。


この答えはC ++に関するものではないようです。C ++では、structクラス(public/ private/ protected、継承など)を宣言します。
melpomene 2017年

-3

**更新:**この返信は無視してください。構造体の場合、値が初期化されていない可能性を考慮していませんでしたが、たまたま0でした。構造体とクラスの間に初期化の違いはありません。


構造体とクラスのデフォルトの初期化に関係する別の違いを見ています。

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();
}

そのコードを実行して、myTesterを調べます。m_Fooの場合、構造体m_Foo.aは0に初期化されていますが、m_Barの場合、クラスm_Bar.aは初期化されていません。したがって、構造体とクラスのデフォルトコンストラクターの動作に違いがあるように見えます。これはVisual Studioで見ています。


1
m_Foo.a初期化されたとどのように判断しましたか?初期化されておらず、たまたまそうだったとしたらどう0でしょうか?
melpomene 2017年

ええと、私はしませんでした。私の悪い。これは、構造体とクラスの違いではありません。初期化特性は同じです。
Eric Hill

-4

構造体とクラスの主な違いは、構造体では異なるデータ型のデータ変数しか宣言できないのに対し、クラスではデータ変数、メンバー関数を宣言できるため、関数を介してデータ変数を操作できることです。

->私がクラスと構造体で見つけるもう一つの便利なことは、プログラムにファイルを実装するときに、構造体のいくつかの操作を新しい操作のセットごとに何度も実行したい場合、別の関数を作成する必要があり、構造体のオブジェクトをファイルから読み込んだ後、それに対していくつかの操作を行うために渡します。クラスにいる間、毎回必要なデータにいくつかの操作を行う関数を作成した場合、ファイルからオブジェクトを読み取って関数を呼び出すだけで簡単にできます。

しかし、それはプログラマーがどのように適切であるかを判断することに依存します...私によると、それはOOPをサポートしているという理由だけで毎回クラスを好み、それがほとんどすべての言語で実装されている理由であり、すべての時間プログラミングの素晴らしい機能です;- )

そして、ええ、私が言及するのを忘れていた最も忘れられない違いは、クラスがデータの非表示をサポートし、構造体がサポートしないときに組み込みのデータ型で実行される操作もサポートすることです!


1
C ++ではstructメンバー関数を持つことができます
chtz

@chtzありがとう...私はこの機能について今知った...どうもありがとう..私はあなたほど専門家ではない初心者なので、将来的にはみんなからのアドバイスも必要です:-)
Yug Rawal

そして実際には、メンバー関数はそのより広い意味で意図されています。structコンストラクタ、メンバー関数、およびディストラクタ(おそらく仮想、おそらくプライベート、保護またはパブリック)を持つことができます。彼らは継承することができ、継承されます。だから実際…クラスが持つことができるすべてのもの。一般的な慣習は、Cでstructとして宣言したものをstructで宣言し、プライベート変数と保護変数、仮想関数、ctorとdtorなどを宣言する場合はクラスとして宣言することです。しかし、それは単なる慣習であり、言語によって強制されていません
Gian Paolo

-5

他の違いが見つかりました。クラスでコンストラクタを定義しない場合、コンパイラがコンストラクタを定義します。しかし、構造体では、コンストラクタを定義しない場合、コンパイラもコンストラクタを定義しません。そのため、実際にはコンストラクタが不要な場合もありますが、構造体の方が適しています(パフォーマンスのヒント)。そして、私の悪い英語をごめんなさい。


4
本当じゃない。この点structで、classキーワードで定義されたクラスとキーワードで定義されたクラスの間に違いはありません。
イメット、2011

コンストラクタなしで構造体を使用すると、コンストラクタなしのクラスよりも速度が速くなります。
アリ

@アリいいえ、あなたはしません。
オービットでの軽量レース

-5

クラスは参照タイプであり、構造は値タイプです。
クラスが参照型であると言うと、
基本的にインスタンス変数のアドレスが含まれます。

例えば:

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.
}

メインメソッドで
は、このクラスにメモリを割り当て
、そのベースアドレスをMyClassタイプの変数(_myClassObject2)に格納する新しい演算子を使用して、このクラスのインスタンスを作成できます。

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

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

上記のプログラムでは、MyClass _myClassObject2 = _myClassObject1; 命令は、MyClassタイプの両方の変数が

  1. myClassObject1
  2. myClassObject2

同じメモリ位置を指します。
基本的に、同じメモリロケーションを同じタイプの別の変数に割り当てます。

したがって、オブジェクトタイプMyClassのいずれかで行った変更は
、両方が同じメモリロケーションを指しているため、別のオブジェクトに影響を与えます。

「_myClassObject1.DataMember = 10;」この行では、オブジェクトの両方のデータメンバーに値10が含まれます。
"_myClassObject2.DataMember = 20;" この行では、オブジェクトの両方のデータメンバーに値20が含まれます。
最終的に、ポインターを介してオブジェクトのデータメンバーにアクセスします。

クラスとは異なり、構造体は値型です。例えば:

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;
}

上記のプログラムでは、
新しい演算子を使用してMyStructure型のオブジェクトをインスタンス化し、MyStructure型の
_myStructObject変数にアドレスを格納
し、 "_ myStructObject1.DataMember = 10"を使用して構造体のデータメンバーに値10を割り当てます。

次の行では、
MyStructure型の別の変数_myStructObject2を宣言し、それに_myStructObject1を割り当てています。
ここで、.NET C#コンパイラは_myStructureObject1オブジェクトの別のコピーを作成し、
そのメモリ位置をMyStructure変数_myStructObject2に割り当てます。

したがって、_myStructObject1に加えた変更は、MyStructrueタイプの別の変数_myStructObject2に影響を与えることはありません。
そのため、構造体は値型です。

したがって、クラスの直接の基本クラスはオブジェクトであり、構造の直接の基本クラスはオブジェクトから継承するValueTypeです。
クラスは継承をサポートしますが、構造体はサポートしません。

どのように言っているのですか?
そしてその背後にある理由は何ですか?
答えはクラスです。

抽象的、封印済み、静的、部分的であり、プライベート、保護、内部保護はできません。


4
これはc#の質問に答えようとしていると思いますか?質問はc ++に関するものであり、それがこの答えを不正確にしますよね?
smw 2014

@smwは絶対に、彼はサンプルコードをC#で記述しており、C ++ structとの間で渡されるパラメーターに違いがないことを確認するためにここに来ましたclass。ここでは誰もそれについて言及しておらず、ウェブ全体についても言及していません。したがって、これはC ++にも当てはまらないと思います。
John

これは有効なC#コードでもありません-キーワードはすべて間違っています。「Public」、「Static」、「Int」、および「Class」は大文字にしてはならず、「Structure」ではなく「struct」にする必要があります。説明はC#ではほとんど正確です(ただし、構造体は他の構造体ではなくインターフェイスを継承できます)が、C ++に関するものだったため、質問には回答しません...
Darrel Hoffman

2
この答えはまったくナンセンスです。それは、コード例としてVisual BasicとC#の奇妙な組み合わせを使用しており、「クラスは参照型であり、構造は値型」です... .NET(つまりC#)にのみ適用され、C ++には適用されません。あなたは間違った部屋にいます、おい。あなたが属している場所です:stackoverflow.com/questions/13049
TheFlash

しかし、この答えは、C(++)にも同じことが当てはまり、構造体が値型のように使用されることを示しています。int a = 3; int b = a;などMyStruct a=MyStruct("data"); MyStruct b = a;
ラッキードナルド2017年

-8

構造とクラスには3つの基本的な違いがあります

1st-メモリは、スタックメモリ内の構造体(プログラミング言語に近い)に予約されています。スタックメモリ内のクラスが参照用にのみ予約され、実際のメモリはヒープメモリに予約されています。

2Nd-デフォルトでは、クラスがプライベートとして扱われるかどうかにかかわらず、構造はパブリックとして扱われます。

3Rd-構造内でコードを再利用することはできませんが、クラスでは、継承と呼ばれる多くの時間で同じコードを再利用できます


2
C ++構造体は継承と抽象メソッドをサポートします。構造とクラスは同じ方法で割り当てられます。「新しい」でインスタンス化されていなくても、ヒープにクラスを割り当てることは、組み込みシステムでは意味がありません。
JCMS 2015年

2
#1も間違っています。スタックは、そのタイプの何かをローカル変数として宣言するときに使用され、ヒープは「new」演算子を使用するときに使用されます。
Score_Under
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.