2008-09-24 57 views
1

我正在開發一個相當複雜的項目,如果您願意(只是爲了好玩)定製加密程序,並且在設計我的代碼佈局時遇到了這個問題。C++函數列表

我有很多功能,我希望能夠通過索引來調用。具體來說,我需要能夠隨機調用一個用於加密過程,但是隨後通過解密過程中的特定索引解決該問題。

我正在考慮一個經典的函數數組,但我主要關心的是函數數組維護會很棘手,而且有點難看。 (目標是將每個函數對都放在一個單獨的文件中,以減少編譯時間並使代碼更易於管理。)有沒有人有更優雅的C++解決方案作爲函數數組的替代方案?速度不是真正的問題,我更擔心可維護性。

-Nicholas

回答

2

你可以寫類似:

class EncryptionFunction 
{ 
public: 
    virtual Foo Run(Bar input) = 0; 
    virtual ~MyFunction() {} 
}; 

class SomeSpecificEncryptionFunction : public EncryptionFunction 
{ 
    // override the Run function 
}; 

// ... 

std::vector<EncryptionFunction*> functions; 

// ... 

functions[2]->Run(data); 

你可以使用operator()代替Run作爲函數名,如果你喜歡。

0

具有限定可充當很像一個函數,但是大致更好一起工作的操作者()方法的對象。

5

函數數組有什麼問題?

您需要通過索引調用函數。所以他們必須被放入一些「按指數索引」結構莫名其妙。數組可能是適合這種需求的最簡單的結構。

例(打字了我的頭,可能無法進行編譯):

struct FunctionPair { 
    EncodeFunction encode; 
    DecodeFunction decode; 
}; 
FunctionPair g_Functions[] = { 
    { MyEncode1, MyDecode1 }, 
    { MySuperEncode, MySuperDecode }, 
    { MyTurboEncode, MyTurboDecode }, 
}; 

什麼是在上面的辦法「醜」或「難以維持」?

0

多態可以做到這一點:你可以按照策略模式,考慮每個策略來實現你的一個函數(或它們的一對)。

然後創建一個策略向量,並使用這個而不是函數列表。

但坦率地說,我沒有看到函數數組的問題;您可以輕鬆創建一個typedef來簡化可讀性。有效地,當使用策略模式時,您將得到完全相同的文件結構。

// functiontype.h 
typedef bool (*forwardfunction)(double*, double*); 

// f1.h 
#include "functiontype.h" 
bool f1(double*, double*); 

// f1.c 
#include "functiontype.h" 
#include "f1.h" 
bool f1(double* p1, double* p2) { return false; } 


// functioncontainer.c  
#include "functiontype.h" 
#include "f1.h" 
#include "f2.h" 
#include "f3.h" 

forwardfunction my_functions[] = { f1, f2, f3 }; 
  • 函數聲明和定義在不同的文件 - 編譯時間是確定的。
  • 的功能分組是在一個單獨的文件,具有依賴性的聲明僅
0

更多信息如果您在boost::signals庫望去,你會看到一個例子很不錯的,這是非常優雅:
假設你有4種功能,如:

void print_sum(float x, float y) 
{ 
    std::cout << "The sum is " << x+y << std::endl; 
} 

void print_product(float x, float y) 
{ 
    std::cout << "The product is " << x*y << std::endl; 
} 

void print_difference(float x, float y) 
{ 
    std::cout << "The difference is " << x-y << std::endl; 
} 

void print_quotient(float x, float y) 
{ 
    std::cout << "The quotient is " << x/y << std::endl; 
} 

然後,如果你想叫他們一個優雅的方式嘗試:

boost::signal<void (float, float)> sig; 

sig.connect(&print_sum); 
sig.connect(&print_product); 
sig.connect(&print_difference); 
sig.connect(&print_quotient); 

sig(5, 3); 

,輸出是:

The sum is 8 
The product is 15 
The difference is 2 
The quotient is 1.66667 
+0

建議:爲代碼示例使用 '代碼示例' 格式。這是答案編輯器中的「零和」按鈕。 – jwfearn 2008-09-24 15:39:05

0

您需要使用一個函數指針數組。唯一的問題是所有的函數都必須具有基本相同的原型,只有函數的名稱和傳入的參數名稱可以有所不同。返回類型和參數類型(以及參數和順序的數量)必須相同。

int Proto1(void); 
int Proto2(void); 
int Proto3(void); 

int (*functinPointer[3])(void) = 
{ 
    Proto1, 
    Proto2, 
    Proto3 
}; 

然後,你可以做這樣的事情:

int iFuncIdx = 0; 
int iRetCode = functinPointer[iFuncIdx++]();