偽の友人?C ++、C#、Javaと比較したCのキーワード「静的」


8

私にとって、staticC でのキーワードの使用、およびC#やJavaなどの言語の使用は、"to be"(英語)や "bekommen"(ドイツ語)(=英語で "to get")などの「偽の友達」です。

C staticでは、関数または変数には、同じソースファイル内の関数を介してのみアクセスできます。これはprivate、C ++、Java、およびC#の関数とメンバーに相当します。

C ++では、JavaとC#staticは、メソッドがクラスインスタンスのメンバーではないことを意味しますが、事実上、C関数と名前空間に似ています。

私見これら2つの概念はかなり異なるので、なぜC ++以降のJavaおよびC#の設計者はstaticその動作のキーワードを選択したのですか?見落としている論理的な接続はありますか?

編集 私は知っstaticていprivateます、CではC ++ と同様の方法でアクセシビリティを管理しませんが、そのように使用できます、https://stackoverflow.com/a/1479639/124983を参照してください

回答:


9

私はBjarne Stroustrup(C ++の発明者)によるC ++の設計に関する本を持っています。私はここにそれを持っていないので、今は正確な引用を検索できませんが、staticC ++ に追加したときに、Cでの意味が完全に理解できなかったと認めています。だから、C ++では、 Cとは意味が異なります。

JavaとC#はC ++から意味を継承しました。


この回答を賛成するためだけにここにアカウントを作成しました!これは、ソフトウェア開発者としての人生で見逃したくない素晴らしい情報です。
Maverick283

@ Maverick283それはこの本です:C ++のデザインと進化
Jesper

14

特に、C ++ではの両方の用途がありstatic、どこかに3つ目があると思います。

一般的に、Cの使用はstatic、英語の単語の使用法にはまったく対応していないと思いますが、たとえば、メンバー変数staticとしてstaticは、もっと理にかなっていると思います。

言語デザイナーとして、言語に導入するキーワードの数を減らし、コードの使用を禁止するかなりのインセンティブがあることを覚えておいてください。特にC ++のようにCとソース互換性を確保しようとしstaticていて、キーワードがすでに存在している場合は、それらを再利用してC ++としてコンパイルしようとするCプログラムを壊すことはできませんでした。

編集:私は3分の1があることを知っていました。Cには関数レベルのstatic変数があります。staticメンバーは、ちょうどこの機能のスコープのバージョンです。したがって、両方の使用はstaticC に由来します。


3
cは、静的の2つの用途(リンケージと寿命)を有しているC ++の両方これらのクラス一つを有する
JKを。

1
@jk:クラスのバージョンは関数レベルと同じstaticで、関数ではなくクラスをスコープとしています。
DeadMG 2012年

1
@jk。多くのstatic人は、Cで3つの用途があると考えています(関数スコープ変数、変数のコンパイルユニットスコープ、関数のコンパイルユニットスコープ)。これら3つのケース(リンケージとライフタイム)で2つの同じことを実際に行っています。これについてのあなたの意見を共有します。悲しいことに、Cでのstaticの3つの使用法の見方がより一般的です。それは人々がそれを使う方法を理解するのを助けますが、それが実際にどのように機能するかではありません。
Gauthier 2012年

staticの新しいC99の使用法を忘れています:stackoverflow.com/questions/3430315/…–
オースティン


8

C ++では、static次の4つの用途があります。

  • グローバル(ファイルレベル)関数と変数の宣言:staticでは、内部リンケージを指定します。つまり、シンボルはその1つのコンパイル単位(ヘッダーではなく、.cpp / cc / whateverファイル)でのみ使用されます。これは、あなたが「プライベート」と呼んでいるものです。

  • ローカル変数:静的ストレージ期間は、変数が関数呼び出し間でその値を保持する必要があることを指定します。

  • データメンバー:静的データメンバーは、クラスのインスタンス間で共有されます(つまり、メンバーのコピーは1つだけです)。これは、C#やJava staticに似ています。

  • メンバー関数:静的メンバー関数は、暗黙のthisポインターを持たないメンバー関数です。インスタンスなしで呼び出すことができます。これもC#やJavaによく似ています。

したがって、ご覧のとおり、上記の意味の2つを落としました。スコーピングに関しては、その理由は非常に理解できます。C#とJava(およびC ++)の両方が名前空間に依存してそれを行っています。おそらくC ++には、下位互換性のための内部リンケージ機能があります。静的ローカル変数を破棄することはおそらく2つあります。1回目は、その結果を完全に理解するのは難しい場合があり、これらの言語は単純化を目指しています。第2に、JavaとC#の両方にガベージコレクターがあり、(私は想像できる)そのような動作の実装を困難にします。


「C ++には、おそらく下位互換性のための内部リンケージ機能があります。」-(IIRC)を追加すると、C ++標準は最初にこの使用を非推奨にしstatic(匿名の名前空間を推奨)、次に現在のインカネーションでC ++ 11 staticがこの使用を非推奨にしました。(すべてIIRC)
マーティンバ

本当に?少なくとも2つの主流のもの(gccとMSVC)で動作したため、コンパイラーはこの非推奨を尊重しなかったと確信しています。
タマシュSzelei

私が知る限り、コンパイラはそれを捨てませんでした。それでも私は'98 / '03規格がそれを非推奨にしたと思います。私のコメントで実際に言いたかったのは、内部リンケージのことは明らかにC ++でも役立つと考えられる機能であるため、下位互換性のためだけにあるわけではありません。
Martin Ba

同じことを行う「c ++-y」の方法は、匿名の名前空間で宣言することです。
タマシュSzelei

「匿名の名前空間で宣言すること」-技術的に同じではないことを除いて。(これ以上の参照がないことをお詫びしますが、それを調べる時間はありません。(それはcomp.lang.c ++。moderated NGで言及されていたと思います。おそらく、標準のペーパーでいくつかの参照を見つけることができますWG21の...)
Martin Ba

3

C ++は、Cからそれを採用しました。C++は、既存のコードを壊すことを最小限にするために、新しいキーワードを導入する代わりに既存のキーワードを再利用することを好みます。

JavaとC#はそれをC ++から取得しました。


3

C staticはアクセシビリティを管理せず、提案さprivateれた方法に似ていません。

ファイルスコープで、それはの可用性を管理する名前(リンカ記号)、いない事を-あなたはへのポインタを渡すことができstatic、それが別のファイル内のコードに定義された翻訳単位から関数やグローバル、そして、それは罰金を動作します。

これを行うC ++の方法(DeadMGによると、Cの方法もまだ利用可能です)では、匿名の名前空間を使用します。

関数スコープでは、それは本質的にのみアクセス可能であるグローバルとローカル変数置き換え、その関数の内部で(再び名前を!) -これはC ++で同じである(そう、もっとありませんC ++ Y 、それを行う方法が) 。

C ++ staticがクラスメンバーの修飾子を使用した理由については、これは、導入される新しいキーワードの数を最小限に抑えることであると言うのがおそらく正しいでしょう。(比較のために最近autoが再利用されていることに注意してください)。

クラスごとのデータを静的に(つまり、インスタンスごとに暗黙的に動的に)呼び出すことは、私にはかなり直感的に思えますが、その直感を形成するプロセスを覚えていないため、開始時に意味があるかどうかについて客観的にコメントすることはできませんアウト。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.