2015-01-14 33 views
-1

我需要一个返回变量的函数,但我不想指定它将返回的变量类型(这是要确定的以后使用)。C++从函数中返回多个类型引用并将它们转换为我们需要的类型

// unknownType is a char, because it uses only one byte of memory 
typedef char unknownType; 

unknownType& func (bool typeSelector) { 
    // let's say we want to return double and int type 
    double dblVal = 3.5; 
    int intVal = 5; 

    // return type depends on typeSelector's state 
    if (typeSelector == true) 
     return (unknownType&)dblVal; 
    else 
     return (unknownType&)intVal; 
} 

,然后我会使用这样的:

double dblVal = (double&) func(true); 

std::cout << dblVal << std::endl; 
std::cout << (int&) func(false); 

上面的代码只是正常(如果我不试图返回更复杂的对象,像的std :: string例如,但这对我的需求是可以的);我在linux和windows上编译过它。但我不确定它是否是我的问题的便携式解决方案。

我的问题是:在这段代码中有什么可以分解我的程序,使之无用吗?性能条款的效率如何?

编辑:为什么我不能在这里使用模板

我有一个基类:

class Base { 
public: 
    virtual unknownType& getValue() = 0; 
}; 

然后一对夫妇的派生类,所包含不同类型的变量:

class DerivedDbl : public Base { 
private: 
    double value; 
public: 
    DerivedDbl (double val) : value(val) {} 

    unknownType& getValue() { 
     double toReturn = value; 
     return (unknownType&)toReturn; 
    } 
}; 

class DerivedInt : public Base { 
private: 
    int value; 
public: 
    DerivedInt (int val) : value(val) {} 

    unknownType& getValue() { 
     int toReturn = value; 
     return (unknownType&)toReturn; 
    } 
}; 

然后我有一个类,其存储派生类,并就他们的一些操作:

class Storage { 
private: 
    std::vector <Base*> vec; 
public: 
    void operator+= (Base& obj) { vec.push_back(&obj); } 

    unknownType& operator[] (int ID) { 
     return vec[ID]->getValue(); 
    } 
}; 

我希望能够获得存储的派生类的变量值有时(我知道哪一个我已经添加,所以我知道他们的类型),但我不认为创建单独的getter方法每一个不那么优雅的方式来获得他们,像这样的代码看起来更清晰的对我说:

DerivedDbl derivedDbl(3.5); 
DerivedInt derivedInt(5); 

Storage storage; 
storage += derivedDbl; 
storage += derivedInt; 

std::cout << (double&)storage[0] << std::endl; 
std::cout << (int&)storage[1]; 

但也许有些事我已经错过了,并有可能使用不同的方法做同样的事情(我试过模板,并没有提出任何好的想法,你们dissuaded无效指针,工会和结构需要更多的内存)。

+1

使用模板? – quantdev

+4

_“上面的代码工作得很好”_我严重怀疑这一点。你刚刚遇到未定义的行为。不要使用像这样的转换,而是使用模板来代替前面提到的模板。 –

+0

@quantdev:事情是,我做不到。我会立刻编辑这篇文章来解释原因。 – Jezor

回答

1

您正在返回对局部变量的引用。这有时似乎有效,但它是不确定的行为,并会在某个时候破坏你的程序。

如果你真的需要一个虚函数,它应该可能返回某种类型的隐藏类(例如boost :: any)。然后,您可以将返回的值转换为正确的类型。

或者,您可以使该函数非虚拟,并从基本类型转换为适当的派生类型。派生类可以返回你实际需要的类型。

模板可以用来促进这一行为,例如:

class Base 
{ 
public: 

    virtual ~Base() { } 
}; 

template<class T> 
class ValueType : public Base 
{ 
public: 

    explicit ValueType(T value): value(value) { } 

    T& GetValue() 
    { 
     return value; 
    } 

private: 

    T value; 
} 

struct Storage 
{ 
    std::vector<Base*> objects; 

    template<class T> 
    T& GetValue(unsigned int index) 
    { 
     auto derived = dynamic_cast<ValueType<T>*>(objects[index]); 

     return derived->GetValue(); 
    } 
}; 

编辑:改变访问控制。

+0

我想过关于auto说明符,但我没有一个兼容C++ 11的编译器 - 我想我必须得到一个,谢谢! – Jezor

+0

@Jezor注意''auto'不需要代码,如果你没有C++ 11,你可以用'ValueType *'代替它。 – user2079303

+0

@ user2079303你能编辑你的代码来匹配我的吗?我试图按照我想使用它的方式实现它,并且出现错误(例如“'Base'是'ValueType '的不可访问的基础)。我会非常感谢! – Jezor

相关问题