0

次のシナリオでは、ある条件に基づいてデータのタイプが異なる可能性があります。

class myClass {
public:
    myclass() {
        if (condition1) {
          bool boolValue = false;
          data = boolValue;
        } else if (condition2) {
          int intValue = 0;
          data = intValue;
        } else if (condition3) {
          unsigned int unsignedIntValue = 0;
          data = unsignedIntValue;
        } else if (condition4) {
          long longValue = 0;
          data = longValue;
        } else if (condition5) {
          double doubleValue = 0.0;
          data = doubleValue;
        } else if (condition6) {
          float floatValue = 0.0;
          data = floatValue;
        } else if (condition7) {
          char *buffer = new char[10];
          data = buffer;
        }
    }

    void* getData() const { return data; }

private:
    void *data;
}

たまたま、私のvoidポインターが指す値は、厳密に各ステートメント内にあります。したがって、getData()で返されるものは有効でない可能性があります。私がデータを取得した場合、それは単に私が指しているメモリ位置がまだ上書きされていないためです。

私が思いついた解決策はこれです:

class myClass {
public:
    myclass() {
        if (condition1) {
          boolValue = false;
          data = boolValue;
        } else if (condition2) {
          intValue = 0;
          data = intValue;
        } else if (condition3) {
          unsignedIntValue = 0;
          data = unsignedIntValue;
        } else if (condition4) {
          longValue = 0;
          data = longValue;
        } else if (condition5) {
          doubleValue = 0.0;
          data = doubleValue;
        } else if (condition6) {
          floatValue = 0.0;
          data = floatValue;
        } else if (condition7) {
          buffer = new char[10];
          data = buffer;
        }
    }

    void* getData() const { return data; }

private:
    void *data;
    bool boolValue;
    int intValue;
    unsigned int unsignedIntValue;
    long longValue;
    double doubleValue;
    float floatValue;
    char *buffer;
}


これを行うにはもっとエレガントな方法があるに違いないと思っていました。助言がありますか?

4

2 に答える 2

1

ユニオンを使用してメモリに数ビットを保存し、ポインタ キャストを使用してユニオンから値を取得できます。

#include<iostream>
using namespace std;

class myClass {
public:
    myClass(char *str){
        data.str = str;
    }
    myClass(double d){
        data.d = d;
    }
    myClass(float f){
        data.f = f;
    }

    void *getData() { return (void*)&data; }
private:
    union {
        double d;
        float f;
        char *str;
    } data;
};

int main(){
    myClass c(2.0);
    cout << *(double*)c.getData() << endl;

    myClass f(3.0f);
    cout << *(float*)f.getData() << endl;

    myClass s("test");
    cout << *(char**)s.getData() << endl;

    system("pause");
}

/* prints
2
3
test
*/
于 2012-11-28T12:14:44.097 に答える
1

オブジェクトを作成した後にデータの型を変更する必要がない場合は、テンプレート クラスを使用できます。

template <typename T>
class myBaseClass {
public:
    // Declare common functions here.
    T getData()
    { return data; }

protected:
    T data;

protected:
    // Disallow constructing instances of this class outside the child classes.
    myBaseClass(T val) : data(val) { }
};

template <typename T>
class myClass: public myBaseClass<T> {
public:
    myClass() : myBaseClass<T>(0) { }
};

次に、次のことを専門としchar*ます。

template <>
class myClass<char*>: public myBaseClass<char*> {
public:
    myClass() : myBaseClass(new char[10]) { }
};

次に、次のようにインスタンスを作成します。

myClass<int> a;
myClass<float> b;
myClass<char*> c;
// etc.
int i = a.getData();
float f = b.getData();
char* str = c.getData();
于 2012-11-28T12:29:41.443 に答える