首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为C++变量类灵活地在字符串、整型、双精度之间转换

为C++变量类灵活地在字符串、整型、双精度之间转换
EN

Stack Overflow用户
提问于 2011-11-18 03:54:12
回答 8查看 13.2K关注 0票数 12

我正在实现一个变体类(不使用boost),我想知道如何处理存储任何字符串、整数或双精度值并通过ToString()、ToInt()或ToDouble()自动将其转换为所需类型的情况。

例如,

代码语言:javascript
运行
复制
Variant a = 7;
cout << "The answer is" + a.ToString() << endl; // should print "The answer is 7"
a = "7.4";
double &b = a.ToDouble();
b += 1;
cout << a.ToString() << endl; // should print 8.4

ToXXX函数应返回要转换为的类型的引用。现在,我有一段代码,它可以返回与最初分配给它的类型相同的类型( Variant a = Int(7); a.ToInt() works),并在分配的类型与您想要转换的类型不同时引发异常。

抱歉,使用boost不是一种选择。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-11-25 15:18:16

代码语言:javascript
运行
复制
    #include <string>
    #include <iostream>
    class Variant{
    public:
        Variant(){
            data.type = UNKOWN;
            data.intVal = 0;
        }
        Variant(int v){
            data.type = INT;
            data.intVal = v;
        }
        Variant(double v){
            data.type = DOUBLE;
            data.realVal = v;
        }
        Variant(std::string v){
            data.type = STRING;
            data.strVal = new std::string(v);
        }
            //the missing copy constructor
             Variant(Variant const& other)
             {
                *this = other;// redirect to the copy assignment
              }

        ~Variant(){
            if(STRING == data.type){
                delete data.strVal;
            }
        }

        Variant& operator = (const Variant& other){
            if(this != &other)
            {
                if(STRING == data.type){
                    delete data.strVal;
                }

                switch(other.data.type){
                case STRING:{
                        data.strVal = new std::string(*(other.data.strVal));
                        data.type = STRING;
                        break;
                    }
                default:{
                        memcpy(this, &other, sizeof(Variant));
                        break;
                    }           
                }
            }
            return *this;
        }
        Variant& operator = (int newVal){
            if(STRING == data.type){
                delete data.strVal;
            }
            data.type = INT;
            data.intVal= newVal;
            return *this;
        }

        Variant& operator = (double newVal){
            if(STRING == data.type){
                delete data.strVal;
            }
            data.type = DOUBLE;
            data.realVal= newVal;
            return *this;
        }

        Variant& operator = (std::string& newVal){
            if(STRING == data.type){
                delete data.strVal;
            }
            data.type = STRING;
            data.strVal= new std::string(newVal);
            return *this;
        }
        operator int&() {
            if(INT == data.type)
            {
                return data.intVal;
            }
            //do type conversion if you like
            throw std::runtime_error("bad cast");
        }

        operator double&()  {
            if(DOUBLE == data.type){
                return data.realVal;
            }
            //do type conversion if you like
            throw std::runtime_error("bad cast");
        }
        operator std::string&() {
            if(STRING == data.type){
                return *data.strVal;
            }
            throw std::runtime_error("bad cast");
        }
    private:
        enum Type{
            UNKOWN=0,
            INT,
            DOUBLE,
            STRING
        };
        struct{
            Type type;
            union 
            {
                int intVal;
                double realVal;
                std::string* strVal;
            };
        } data;
    };


    int main(){
        Variant v("this is string");//string
        v=1;//int
        v=1.0;//double
        v=std::string("another string");//
        Variant v2; //unkown type
        v2=v;//string
        std::cout << (std::string&)v2 << std::endl;
        return 0;
    }    
票数 11
EN

Stack Overflow用户

发布于 2011-11-20 00:18:39

要实现这样的东西,您需要能够更改存储类型,因为如果用户通过引用更改变量,他希望更改会影响存储值,因此我将编写如下代码:

代码语言:javascript
运行
复制
class Variant
{
private:
    enum StoreType
    {
        Integer,
        Float,
        String,
    }
    store_type;

    union
    {
       int * as_integer;
       double * as_double;
       std::string * as_string;
    }
    store_pointer;

    // convert to type
    void integer_to_double();
    void integer_to_string();
    void double_to_integer();
    void double_to_string();
    void string_to_integer();
    void string_to_double();

public:

...

    int & ToInt()
    {
        switch (store_type)
        {
            case Integer: break;
            case Double: double_to_integer(); break;
            case String: string_to_integer(); break;
        }
        return * as_integer;
    }

...

}
票数 7
EN

Stack Overflow用户

发布于 2011-11-25 05:15:35

我自己实现了一个简单的变体类(没有使用第三方库)。每个ToXxx函数都包含一个基于m_type的枚举(指示当前持有的类型的枚举)。对于字符串转换(从和到),我使用std::stringstream。这很微不足道,真的。就像叫鸭子建议的那样。

备注:如果打算频繁调用相同值的字符串转换,我会将其缓存。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8173389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档