2016-08-02 11 views
1

私が意味することを示すために、C言語を例として使用します。変数の型はそれ自身変数ですか?

struct parent 
{ 
    int x; 
    char y; 
}; 
struct child 
{ 
    char y; 
    int x; 
}; 

int foo(void * s, type obj_type) 
{ 
    // the casting is done using a "type" variable 
    obj_type obj = (obj_type) s; 
    return obj->x; 
} 

int main(int argc, char** argv) 
{ 
    type obj_type = struct parent *; 
    struct parent p; 
    p.x = 0; 

    //returns 0 
    foo(&p, obj_type); 

    obj_type = struct child *; 
    struct child c; 
    c.x = 5; 

    // returns 5 
    foo(&c, obj_type); 

    return 0; 
} 

あなたが見ることができるように、私はちょうどメモリに静的オフセットを持つことができないので、Xは、両方の構造体のためのメモリ内の異なる場所に配置されます。とにかくこれはCで可能ですか(私が考えることができなかったプリプロセッサの魔法)?私はいいえと思いますが、タイプ自体が変数として使用できる言語はありますか? itsme86が指摘したように、C#は型クラスでこの能力を持っている:私はタイプを中心としたプログラミング

EDITの意味を探るのが大好きです。また、C++のコンセプトやHaskell Typeクラスも興味深い。

+0

私は何をお使いの提示従わないと思います。 'return obj-> x;' int'を返すのですか? –

+0

はい。しかし、型演算子にもよりますが、obj-> xはobjのアドレスにあるかもしれませんし、1バイト離れたオフセットでも構いません。私が欲しいのは、値ではなくタイプを識別するための変数です – m1cky22

+3

あなたが探している機能は[型式イントロスペクション]です(https://en.wikipedia.org/wiki/Type_introspection)。いくつかのオブジェクト指向言語では利用できますが、C言語では使用できません(ただし、すべての構造体の最初のメンバーとして 'type'メンバーを追加することでハックすることができます)。 – user3386109

答えて

2

あなたは後ろに型の安全性を残す場合は、(stddef.hから)offsetofを使用することができます。

int foo(unsigned char * s, size_t offset) 
{ 
    int* ptr = (int*)(s + offset); 
    return *ptr; 
} 

foo((unsigned char*)&p, offsetof(struct parent, x)); 

しかし、私は実際にそれをお勧めしません。

+0

これは間違いなく私が探していた興味深い結果を得る方法です。しかし、私が求めている主な理由は、変数型が値として型を含むことができるかどうか、つまり「型t = int」を調べたいからです。これはどの言語でも可能ですか? – m1cky22

0

はJavaでは、あなたは反射のAPIを介して型情報にアクセスすることができます。次に例を示します。

package stackoverflow; 

import java.util.Arrays; 

public class MyClass { 
    public static void main(String[] args) { 
     MyClass myInstance = new MyClass(42, "foo"); 
     Class<MyClass> myClass = MyClass.class; 
     System.out.println(myInstance instanceof MyClass); 
     System.out.println(myInstance.getClass().equals(myClass)); 
     System.out.println(myClass.getName()); 
     System.out.println(Arrays.toString(myClass.getDeclaredFields())); 
     System.out.println(Arrays.toString(myClass.getDeclaredMethods())); 
    } 

    private final int i; 
    private final String s; 

    public MyClass(int i, String s) { 
     this.i = i; 
     this.s = s; 
    } 

    public int getI() { 
     return i; 
    } 

    public String getS() { 
     return s; 
    } 
} 

出力:

true 
true 
stackoverflow.MyClass 
[private final int stackoverflow.MyClass.i, private final java.lang.String stackoverflow.MyClass.s] 
[public int stackoverflow.MyClass.getI(), public java.lang.String stackoverflow.MyClass.getS(), public static void stackoverflow.MyClass.main(java.lang.String[])] 

あなたが見ることができるように、MyClass.classは、クラスMyClassに関する情報へのアクセスを提供してジェネリック型java.lang.Class<T>、の目的です。このオブジェクトは、クラスの任意のインスタンスを介して取得することもできます。myInstance.getClass()を参照してください。私はアクセス可能なものを示すためにいくつかの例を挙げました。 Classオブジェクトを使用してクラスの新しいインスタンスを作成することもできます。詳細については、java.lang.reflectパッケージのJavadocを調べることもできます。


これらの情報にのみアクセスできることにご注意ください。たとえば、既存のインスタンスのタイプを変更することはできませんが、これは良いことだと思います。しかし、これはPythonで可能であるように思わ:

Can I dynamically convert an instance of one class to another?

関連する問題