4

短いバージョン:
次の擬似コードを検討してください。

class Foo {
    private:
        abstract type myVar;
} // This class is abstract

この動作を標準のC++でどのように実装しますか?


長いバージョン:
MatlabからC++に多くのObj指向のコードを移植する必要があります。私はMatlabを使用する世界で最も経験の浅い人であり、2007年以降C++を使用していないことに注意してください。

私はこのトピックについてたくさんグーグルで検索しましたが、私の質問に対する適切な答えを見つけることができませんでした。だからここにいる:)

このmatlabクラスがあるとしましょう:

classdef Foo < handle
    properties (Abstract, Dependent)
        A
    end

    properties
        B
    end

    methods (Abstract)
        computeA()
    end

    methods (Access = protected)
        function obj = Foo(bar)
            obj.B = Matlab.BlaBlaBla(bar)
    end
end

このクラス(おそらく)は、コンストラクターが保護されているため、「直接」割り当てることはできません。また、プロパティ「A」は抽象です(これも依存しているという事実はしばらく無視してください)。MathWorksによると、これは次のことを意味します。

  • 具象サブクラスは、Abstract属性なしで抽象プロパティを再定義する必要があり、SetAccess属性とGetAccess属性には、抽象スーパークラスで使用される値と同じ値を使用する必要があります。
  • 抽象プロパティは、アクセスメソッドの設定または取得を定義できず(プロパティアクセスメソッドを参照)、初期値を指定できません。具体的なプロパティを定義するサブクラスは、setまたはgetアクセスメソッドを作成し、初期値を指定できます。

では、このような動作をC ++でどのように正しく変換しますか?私が次のようにした場合、それは正しいでしょうか?(つまり、それは悪い設計慣行ではないということです)

class Foo {
    private:
         type A;
         type B;
    protected:
         virtual void computeA() = 0;
         Foo(type bar) { this.B = SomeFoo(bar); }
}

私が思うこと(そして私は間違っているかもしれません)は、私がそうしているなら、人はしなければならないだろうということです

class Subclass: Foo {
    protected:
        void computeA(){...} 
    public:
        type A() { computeA(); return A; } //This is A getter that grants Dependent behavior
}

または、コンパイル時にエラーが発生します。

私が間違っている?そうするためのより良い方法はありますか?また、Dependentキーワードを翻訳する正しい方法はありますか?

4

1 に答える 1

2

まず第一に、私は質問することが重要だと思います:クラスのパブリックインターフェースは何ですか(その責任は何ですか、それは他の人とどのように相互作用しますか)?

Matlabコードから、答えは次のとおりです。クラスは、プロパティAとB、およびメソッドcomputeAを定義します。Dependentプロパティの理解から、computeA()をパブリックにする必要があるとは思えません(Matlabドキュメントを参照)。コードの残りの部分でこれが必要な場合は、もちろん公開したままにすることもできますが、アクセシビリティを減らすようにしています。

現在、プロパティの概念はC++には存在しません。Matlabの面白い点は、基本クラスがA.get、A.set、またはその両方があるかどうかと、アクセシビリティを決定することです。その理由はわかりませんが、私の目にはあまり意味がないようです。C ++では、プロパティをget/setメソッドに変換します。これらをC++で実装する方法については、この質問を参照してください。選択に応じて、非依存プロパティをメンバーオブジェクトまたはget/setメソッドとして実装できます。

メソッドのパブリックインターフェイスを定義したらすぐに、それを実装する方法について考え始めます。MatlabとC++のメモリ管理は異なることに注意してください(Matlabはコピーオンライトを使用し、メモリ管理を考慮します。これは純粋なC ++には存在しません)。また、(computeAおよび依存プロパティで行われるように)値のキャッシュは、(低速オブジェクト指向の)Matlabコードで必要になる場合がありますが、C++では必ずしも必要ではありません。時期尚早の最適化を回避するには、次のことを行ってください。

class Foo {
    public:
      ClassB B;
      virtual ClassA getA() = 0;
      //define a setA()=0 if you need it here
    protected:
         //I wouldn't force subclasses to have the "caching" of dependent properties, so no virtual void computeA() = 0; 
         Foo(ClassBar const& bar) { this.B = ClassB(bar); /*Note that SomeFoo cannot be assigned to B*/ }
}
class Subclass: public Foo {
    private:
        ClassA A;
    public:
        ClassA getA() { ClassA A; /*compute A*/ return A; } 
}

Aの計算が遅すぎる場合でも、サブクラスで「Aをローカルにキャッシュ」できます。

class Subclass: public Foo {
    private:
        ClassA A;
    public:
        ClassA getA() { /*compute A if required*/ return A; } 
}

本当にAをFooに保存したい場合は、次のように実装します。

class Foo {
    private:
      ClassA A;
    public:
      ClassB B;
      ClassA getA() { if (!A.initialized) A=computeA(); return A; };
    protected:
         virtual ClassA computeA() = 0;
         Foo(ClassBar const& bar) { this.B = ClassB(bar); /*Note that SomeFoo cannot be assigned to B*/ }
}
class Subclass: public Foo {
    protected:             
         virtual ClassA computeA() {...}
}

そして、あなたが実際に(定数)参照または値を渡したいかどうかを常に考えることを忘れないでください...

于 2013-01-16T15:10:49.983 に答える