-2

OOPについて私が最も厄介だと思うのは、メンバー関数に新しい変数が必要であり、この変数がこの関数が呼び出されるオブジェクトを「アタッチ」する必要があるときはいつでも、基本的に新しいプライベートを作成する以外に選択肢がないということです。分野。これは私の意見では醜いです。これは、変数がオブジェクトのインスタンス化で初期化されることを意味し(そして、それを必要とするメソッドを呼び出さないと、変数を使用できない可能性があります)、他のエンティティから隠されていない可能性があります。オブジェクトのプライベートメンバーにアクセスすると、それに加えて、クラス定義が乱雑になる可能性があります(C ++クラスについて考えてみてください。ほとんどの場合、フィールドの定義全体を含むヘッダーが付属しています)。

C ++の用語で言えば、staticグローバル関数の変数に対する修飾子の動作が必要ですが、メンバー関数では、ストレージはオブジェクト内にある必要があります。

多くの言語はわかりませんが、動的計画法の言語の方が簡単だと感じています。Luaについて考えることができます。現在のテーブルに新しいインデックスを追加するだけです。これは、新しい「フィールド」を他の世界から隠すことはありませんが、メタテーブルを改ざんしない限り、Luaのすべてが公開されているため、Luaの考え方では実際には問題になりません。しかし、初期化の問題は解決されています。

だから、私の質問は、これが可能な静的プログラミング言語(つまり、コンパイル時にオブジェクトのレイアウトがわかっている言語)はありますか?

ちなみに、同様の結果を得るためのC ++の適切な回避策はありますか?

4

2 に答える 2

0

あなたが言うようstaticに、static言語での設計では、オブジェクトの設計に関するすべてのことはコンパイル時に対処する必要があり、クラスは実行時にそれを自分で変更することはできません。staticしたがって、どの言語もそのような仕事をすることはできないと思いますdynamic。変数にアクセスするとパフォーマンスが低下するため、static言語コンパイラではコンパイル時にその変数にアクセスするコードを作成しますが、そのような変数の場合はobject-static)が存在する場合、コンパイラは動的ストレージをチェックしてその名前のプロパティが存在するかどうかを確認するための追加のコードを作成する必要があります。これは、C++の現在の設計に悲しみを感じるからです。ただし、一方で、フィールドを変更せずにそれを実行したくない場合は、動的ルックアップに使用できる型のクラスに1つの変数を追加するだけです(たとえば、std::map)そしてその変数を作成してprivate、クラス内のあなた以外の誰もそれにアクセスできないようにします。

class foo {
    std::map<std::string, boost::any> functionVariables;

public:
    void test1() {
        int visitNumber;
        auto i = functionVariables.find( "test1" );
        if( i == functionVariables.end() ) {
            // This is first visit of the function, initialize your variable
            functionVariables["test1"] = (visitNumber = 0);
        } else {
            // It is already initialized, use it
            visitNumber = ++ *boost::any_cast<int>(&*i);
        }
    }
};
于 2012-10-18T22:36:09.987 に答える
0

オブジェクト指向プログラミングの一般的な考え方は、動作をメソッド(関数)のセットとしてカプセル化し、データをインスタンス変数のセットとしてカプセル化することであるため、この動作は、私が考えることができる静的プログラミング言語には存在しません。

ただし、単一のクラスの懸念事項を複数のユニットに分割するというアイデア(モノリシックを少なくするため)は、いくつかの言語で検討されています。アイデアは、オブジェクトの単一のクラス内のさまざまな懸念を分離することです。変数は実行時に作成されませんが(これにより型が非静的になります)、他のユニットとは別のユニットで宣言できます。

これは実際にはC#で利用できるようなものです。実装は純粋に表面的なものですが、単一のクラスを複数の部分クラスとして宣言できます。利点の1つは、関心の分離を行い、クラスによってカプセル化されたすべてのものの単一の大きな宣言を回避することです(別の用途はコード生成シナリオです)。

これにより、次のことが可能になります。

ファイル1:

partial class Foo {
   int X;
   void DoSomethingWithX() {
        X++;
   }
}

ファイル2:

partial class Foo {
   int Y;
   void DoSomethingWithY() {
        Y++;
   }
}
于 2012-10-18T22:43:46.323 に答える