使用void指针

时间:2012-11-28 11:54:02

标签: c++ void-pointers

鉴于以下情况,根据某些条件,我的数据可能属于不同类型。

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;
}


我当时认为必须有更优雅的方式来做到这一点。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可以使用union在内存中保存一些位,然后使用指针转换从联合中获取值:

#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
*/

答案 1 :(得分: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();