ユーザー定義型 Edit

概要 Edit

項目podstructclassinterface
デフォルトコンストラクタのユーザー定義xxox
コンストラクタooox
デストラクタxoox
静的コンストラクタ
静的デストラクタ
ooox
structメンバ変数xoox
objectメンバ変数xoox
メンバ関数oooo
メンバ変数ooox
ガベージコレクタ対象xxoo
インターフェースの継承xxoo
公開修飾子(public/private)ooox
代入オーバーロードxoxx
invariantooox
項目podstructclassinterfaceutility
デフォルトコンストラクタのユーザー定義x *1x *1oxx
コンストラクタoooxx
デストラクタxooxx
静的コンストラクタ
静的デストラクタ
oooxo
メンバ変数oooxx
structメンバ変数xooxx
objectメンバ変数xooxx
メンバ関数oooox
ガベージコレクタ対象xxoox
インターフェースの継承xxoox
公開修飾子(public/private)oooxo
代入オーバーロードxoxxx
invariantoooxx
ver2.0
scope属性xxoxx
inlineメンバ変数oooxx

1 : 全部0で初期化

*1 : 全部0(規定値)で初期化。

structでも許さない理由は,static変数にstructな変数を定義すると,初期化時に関数コールが走ってしまうため。

関数コールは.init初期化が終わった後から呼び出すように統一したい。

interface Edit

  • C#,Dのinterfaceと同じ
  • interfaceは複数にinterfaceを継承することができる
  • 純粋仮装関数にはabstractキーワードを先頭につける
  • <要検討>デフォルト実装を書くことを許す(本当は許さない方が厳密なinterfaceなんですけど)
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
 
-
|
|
|
|
!
interface IButtonListener
{
    // 抽象関数(絶対実装)
    abstract void onButtonPush( in IButton sender )const;
    // デフォルト実装ありの関数
    void onButtonFocused( in IButton sender )const{}
};

class Edit

  • 強制的にobject型を継承している
  • 他の言語でよくあるclassの継承は不可
  • 他の言語でよくあるclassの継承は不可 -> C#のような1つだけ継承できるのはしてもいいんじゃないかと思い始めてる最近
  • interfaceは何個でも継承できる

pod Edit

  • plain object data
  • C言語のstructに近い
  • デフォルトコンストラクタはオブジェクトのメモリ領域を0で初期化する扱いになる

struct Edit

  • 継承のないC++のクラス・D言語のscope classと同じ
  • ガベージコレクト対象ではないので参照を保持することができない

型公開修飾子 - public private(class,interface,pod,struct) Edit

  • デフォルトはpublic
  • 名前空間直下のprivateな型は同じソース内からしかアクセスができない
  • ガベージコレクト対象ではないので,structなオブジェクトインスタンスの参照(オブジェクトハンドル)を保持することができない

utility Edit

  • static関数のみ提供する型,インスタンスを作ることができない。
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 
 
 
 
 
 
 
-
|
|
!
 
 
 
 
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
#spanend
#spandel
// 同じソース内からしかアクセスできない
#spanend
#spandel
private pod A
#spanend
#spandel
{
#spanend
#spandel
};
#spanend
 
#spandel
// 誰でもアクセスできる
#spanend
#spandel
pod B // public pod Bと同じ
#spanend
#spandel
{
#spanend
  A a; // 同じソースなのでOK
#spandel
};
#spanend
#spandel
 
#spanend
#spandel

メンバ公開修飾子 - public private(class,struct) Edit

  • public/privateのみ。protectedは無い。
  • protectedは無い。
  • デフォルトはpublic
  • コロンを使うC++スタイル、メンバ変数・関数に直接記述するJAVAスタイルの両方に対応
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 
-
|
|
|
|
|
|
|
|
|
|
|
!
 
class A
{
    //--- 公開修飾子(デフォルトpublic)
    // C++/Dスタイル
public: 
    void funcPubA(){} // public
private:
    void funcPriA(){} // private
 
    // JAVA/C#/Dスタイル
    public void funcPubB(){} // public
    private void funcPriB(){} // private
 
};

オーバーライドチェック - override(class) Edit

  • D,C#と同じ

不変条件 - invariant(class,pod,struct) Edit

  • (all)Dのinvariantと同じ
  • (all)Dのinvariantとほぼ同じ
    • 呼び出されるタイミング
      • publicなメンバ関数の実行直前・直後
      • ↑ publicメンバ変数によって自動で作成される関数も対象に含む。(メンバ変数の項を参照)
      • コンストラクタの直後
      • デストラクタの直前
    • invariant関数内でpure constメンバ関数以外のメンバ関数を呼び出すことを禁止。
  • <要検討>structで再帰呼び出しされたらどうしよう(classはカウンタ持たせればいいかな)

委譲 - implement(class) Edit

  • interfaceのデフォルト実装を別オブジェクトに委譲するキーワード
    • ↑これってどういう意味だっけ;

委譲 (class) Edit

  • interfaceのデフォルト実装を別オブジェクトに委譲する
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 
-
|
|
!
 
-
|
|
!
 
 
 
 
 
 
 
-
|
|
|
|
|
|
|
!
 
 
 
 
 
 
 
-
|
|
|
|
|
!
 
interface IButtonListener
{
    abstract void onPushed();
    void onFocused(){}
};
class Hoge : IButtonListener
{
public:
    override void onPushed(){}
};
 
#spandel
class A : IButtonListener implement mHoge
#spanend
#spanadd
class A : IButtonListener = mHoge
#spanend
{
    // IButtonListenerの関数を全てmHogeに委譲される
    // implementを使うと自動で次のように展開される
    // override void onPushed(){ mHoge.onPushed(); }
    // override void onFocused(){ mHoge.onFocused(); }
private:
    Hoge mHoge = new Hoge();
    Hoge@ mHoge;
};
 
#spandel
class B : public IButtonListener implement mHoge
#spanend
#spanadd
class B : public IButtonListener = mHoge
#spanend
{
    // onFocusedの関数だけ実装、その他はmHogeにまかせる
    override void onFocused() { /* */ }
private:
    Hoge mHoge = new Hoge();
    Hoge@ mHoge;
};

コンストラクタ - this() (class,pod,struct) Edit

  • (all)D言語の形式を採用し、関数名はthisを使う
  • (all)別コンストラクタ関数コールは可能
  • (all)どのコンストラクタよりも前に.Initデータをメモリ領域にセットされる(D言語と同じふるまいをする)
  • (pod)デフォルトコンストラクタは定義できない(0初期化固定)
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
    
     
    -
    |
    |
    -
    |
    !
    |
    |
    -
    |
    |
    |
    !
    |
    |
    |
    |
    |
    !
    
    class A
    {
    public:
        this()
        {
          mY = mX + 1;
        } 
        this(in int x, in int y)
          : this()
        {
          this();
          mX = x;
          mY = y;
        }
     
        int x = 1; // 直接初期化子がかける(pod,struct限定)
        int y; // 指定がないとデフォルトコンストラクタが呼ばれる
        int mX = 1; // 直接初期化子を書くことが出来る。ただし,コンパイル時に決まる定数しか書けない。
        int mY; // 指定がないとデフォルトコンストラクタが呼ばれる。
    };

デストラクタ - ~this() (class,struct) Edit

  • D言語スタイルを採用
  0
  1
  2
  3
  4
  5
class A
{
public:
    ~this()
    {
    }
};

静的コンストラクタ・デストラクタ - static this(), static ~this() (class,struct,pod) Edit

静的コンストラクタ - static this() (class,struct,pod,utility) Edit

  • D言語と同じ
  • 静的コンストラクタが呼ばれる前に,.initデータがメモリ領域にコピーされる。

メンバ関数/変数 (class,interface,struct,pod) Edit

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
#spanend
#spanadd
class A
#spanend
#spanadd
{
#spanend
    static int hoge = 1;
    static int foo; // hoge * 2を代入したいが,他の変数を参照することができない
    
    static this()
    {
        // この時点で,.initデータがコピー済み。
        // つまり,hogeには1,fooには0(デフォルト値)が代入済み
#spanadd
 
#spanend
        foo = hoge * 2; // ここなら他の変数を参照することができる。
    }
#spanadd
};
#spanend
#spanadd

静的デストラクタ - static ~this() (class,struct,pod,utility) Edit

  • D言語と同じ
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
#spanend
#spanadd
class A
#spanend
#spanadd
{
#spanend
    static ~this()
    {
    }
#spanadd
};
#spanend
#spanadd

静的メンバ関数 (class,interface,pod,struct,utility) Edit

  • D言語と同じ。

静的メンバ変数 (class,pod,struct) Edit

  • D言語と同じ。

メンバ関数 (class,interface,struct,pod) Edit

  • (all)C++でいうメンバ関数のconst修飾子はあり。引数リストの括弧の後ろにconstを付ける。
  • (all)staticメンバ関数が使える。
  • (class,pod,struct)staticメンバ変数が使える。仕様はD言語と同じ。
  • (class,struct)公開修飾子をつけられる
  • (class)抽象関数にoverrideキーワードが使える
  • (interface)メンバ変数は使えない
  • (interface)純粋仮装関数には先頭にabstractキーワードを付ける
  • (interface)デフォルト実装はstatic関数として同じ名前の関数が定義される。
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
 
-
|
|
|
|
|
!
interface IName
{
  string getName(){ return "NoName"; }
  // こう書くと自動でstatic関数が作られる
  // static string getName() { return "NoName"; }
  // IName.getName()でアクセスできる
  // IName.DEFAULT.getName( IName )でアクセスできる
};

メンバ変数 (class,struct,pod) Edit

  • publicなメンバ変数は関数に展開される。
  • こうすることで変数のオフセット情報を知る必要がなくなり,再コンパイルの回数を減らすことができる。
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
    
     
     
     
     
     
    -
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    -
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    !
    |
    !
     
     
    
    #spanend
    #spanadd
    struct Hoge
    #spanend
    #spanadd
    {
    #spanend
      public int a;
      // これは下記のように展開される
      // public ref int __mv_ref_a()
      // {
      //   return a;
      // }
      // public const ref int __mv_ref_a()const
      // {
      //   return a;
      // }
    #spanadd
     
    #spanend
      static void test()
      {
        Hoge h;
        h.a = 3; // h.__mv_ref_a() = 3; に展開される
    #spanadd
     
    #spanend
        h.a = Hoge().a + Hoge().a;
        // 展開後
        // {
        //   Hoge __tv00;
        //   Hoge __tv01;
        //   h.__mv_ref_a() = __tv00.__mv_ref_a() + __tv01.__mv_ref_a();
        // }
    #spanadd
     
    #spanend
        h.a += 3;
        // 展開後
        // h.__mv_ref_a() += 3;
      }
    #spanadd
    }
    #spanend
    #spanadd

inlineメンバ変数 Edit

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 
 
 
 
-
|
|
|
|
|
|
!
 
 
 
 
 
 
 
 
#spanend
#spanadd
class Hoge
#spanend
#spanadd
{
#spanend
  public inline Foo@ a;
  // こうするとメンバ変数にダイレクトにアクセスするようになる。
  // invariantメソッドが実装されていても呼ばれなくなる。
  // Fooのメンバ変数の構成が変更されると再コンパイルが必要になる。
#spanadd
};
#spanend
#spanadd
 
#spanend
#spanadd
 
#spanend
#spanadd

    ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS