2012-03-05 129 views
0

我怎樣才能(在運行時)決定從我的函數返回哪種類型?
這可能嗎?
我認爲這是一個不能確定的問題。返回不同類型

+1

使用多態性,例如,將所有類型包裝在一個接口中(當然這隻適用於用戶定義的類型),或者,你可以聲明你的方法返回'Object'類型,但這不是很優雅 – scibuff 2012-03-05 11:53:01

+0

在一些有限的情況下,你可以使用一個'聯盟'(提供一些歧視它)。一般來說,多態性更好。 – 2012-03-05 11:54:22

+0

@scibuff:你應該發佈這個答案。 – 2012-03-05 11:55:13

回答

-3

使用多態性

public interface MyType { 
    public void doSomething(); 
} 

public class A implements MyType { 
    public void doSomething(){} 
} 

public class B implements MyType { 
    public void doSomething(){} 
} 

public class MyClass { 

    public MyType getData(){ 
     if (/* some condition */){ return new A(); } 
     return new B(); 
    } 

    public void test(){ 
     MyType o = this.getData(); 
     o.doSomething(); 
    } 
} 

然後簡單地返回MyType類型,並直接在該對象上調用doSomething();即你不需要知道返回的類型是A還是B。你所關心的是它實現doSomething。這是多態之美,即沒有更多的醜陋isgetTypeinstanceOf(JAVA)等

+2

誤導,這是一個Java答案爲一個C++的問題,不是一個真正的答案對於這個問題,而是對OP可能不適用的替代方案的建議。請看標籤。 – 2012-03-05 12:16:50

+0

這個例子是Java,問題是關於C++。不過,如果你只關心用戶定義的類型,你可以在C++中做基本相同的事情。你不能在C++中做的事就是返回Object,因爲C++不會自動強制所有的類繼承一個公共的根類型。 – bames53 2012-03-05 12:20:14

+1

@Jacobo你認真嗎?誰關心語言,它是相同的原則無關緊要,如果它是C++,C#,Java,PHP,...... – scibuff 2012-03-05 12:21:52

3

如果使用Boost是一個選項,可以考慮使用Boost.Variant

在類固醇上,您可以將變體想像爲union。它適用於大多數C++類型,並且允許編譯時和運行時多態性,但它不需要類型的通用基類。 主要的缺點是它涉及大量的模板元編程,所以它會給編譯器帶來一些負擔。

這裏有一個簡短的例子來理解這個概念:

typedef boost::variant<float, std::string> MyVariant; 

MyVariant GetInt() { return MyVariant(42); } 
MyVariant GetString() { return MyVariant("foo"); } 

MyVariant v; 
//run-time polymorphism: 
int number = boost::get<int>(v); // this line may throw (basically a dynamic_cast) 

//compile time polymorphism: 
boost::apply_visitor(Visitor(), v); 
// where Visitor is a functor overloading operator() for *all* types in the variant 

更輕質的選擇是Boost.Any,看到this page了比較。

+0

Boost.Any是一個非常重要的選擇,因爲它涉及到刪除類型。但+1推薦Boost.Variant。 – ildjarn 2012-03-05 19:16:25

+0

輕量化可能是一個糟糕的選擇。我想說的是,Any比imiant更容易學習和使用。對困惑感到抱歉。 – ComicSansMS 2012-03-05 22:01:47