2017-02-24 29 views
-2

我想保持我的代碼模塊化。目前,我有我的代碼設置將函數從子類傳遞給父類。但它根本不編譯。現在我想擺脫所有傳遞函數,但保持「模塊化」。保持C++模塊化而不通過類之間的函數

更新:我添加了更多關於我的代碼在做什麼的信息。我仍然排除了我正在做的大部分工作。班級分子正在優化班級的多個實例。 Class Rates正在優化費率內單個函數生成的多個值。

Class Data_Analysis { 
    virtual double find_rms_A (vector<double>) = 0; 
    virtual double find_rms_B (vector<double>) = 0; 
    virtual double find_rms_C (vector<double>) = 0; 
    double E (double (Data_Analysis::*fxn(vector<double>)) { 
     // doing tons of stuff 
     (this->*fxn)(vec); 
     //Simplex is third party library that requires a function that 
     // takes vector<double> and outputs a double 
     //http://www.codeguru.com/cpp/article.php/c17505/Simplex-Optimization-Algorithm-and-Implemetation-in-C-Programming.htm 
     Simplex((this->*fxn)(vec)); 
    } 
}; 

Class Molecule: Data_Analysis { 
    virtual double find_rms_A (vector<double>) { 
     // using variables only declared in Molecule 
     double rms = 0.0 
     for (int data_point_A = 0; data_point_A < num_data_point_A; data_point_A++) { 
      Rates r(data_point_A); 
      r.run_simulation_v1(); 
      rms += r.return_rate(); 
     } 
     return rms; 
    } 

    virtual double find_rms_B (vector<double>) { 
     // using variables only declared in Molecule 
     double rms = 0.0 
     for (int data_point_B = 0; data_point_B < num_data_point_B; data_point_B++) { 
      //do stuff 
      rms += rate; 
     } 
     return rms; 
    } 
    void optimize_A() { 
     // set variables for type of optimization A 
     E(&Data_Analysis::find_rms_A); 
    } 
    void optimize_B() { 
     // // set variables for type of optimization B 
     E(&Data_Analysis::find_rms_B); 
    } 
}; 

Class Rates: Data_Analysis { 
    virtual double find_rms_C (vector<double>) { 
     // using variables only declared in Rates 
     double rms = 0.0 
     for (int data_point_C = 0; data_point_C < num_data_point_C; data_point_C++) { 
      // run simulation that is completely different than anything used in Molecule 
      rms += rate; 
     } 
     return rms; 
    } 
    void optimize_C() { 
     // set variables for type of optimization C 
     E(&Data_Analysis::find_rms_C); 
    } 
}; 

事情我試圖讓路過職能的工作:

Virtual Function 1Virtual Function 2Virtual Function 3: 「不能聲明變量 'R' 是抽象類型的 'CHILD2'」

Pointer Functions 1Pointer Functions 2 :「不能轉換'雙(Child1 :: )(std :: vector)'到'Parent :: fxn {aka double()(std :: vector)}'在初始化中」(星號使斜體。 )

所以,我想重新組織我的代碼來繞過傳遞函數。但我不知道如何做到這一點,而不必擺脫'函數E'並重複函數A-D(又名破壞模塊性)中的代碼。任何提示/建議?

+1

發佈一些真實的代碼,說明你在說什麼。 –

+1

您能否詳細說明您正在嘗試實施的實際使用案例。因爲你的例子看起來太設計了。 – rustyx

+0

這聽起來像一個XY問題。你想用這種奇怪的東西來實現什麼? –

回答

0

如果您要傳遞特定於小孩的功能,請不要通過Parent中定義的虛擬功能來完成。殺死虛擬函數,並將你想要的子特定函數直接傳遞給E.使用std :: bind來包裝Child1Child2 -ness,這樣E就不會關心除參數以外的函數。

class Parent { 
    double E (std::function<double (vector<double>)> fn) { 
     // doing tons of stuff 
     fn(vec); 
    } 
}; 

class Child1: public Parent { 
    double A (vector<double>) { 
     // using variables only declared in Child1 
    } 
    double B (vector<double>) { 
     // using variables only declared in Child1 
    } 
    void F() { 
     E(std::bind(&Child1::A, this, std::placeholders::_1)); 
     E(std::bind(&Child1::B, this, std::placeholders::_1)); 
    } 
}; 

一個設計試金石是:如果沒有任何意義實施中的所有子類的虛函數,它可能不應該是一個......

您也可以使用代替呼叫的lambda。

此外,你確定你想通過價值傳遞一個向量?你可能想通過const引用來代替。

0

至少乍一看,似乎你的問題是由於代碼不夠模塊化而引起的。

它在我看來就像是你將真正的兩個單獨的東西合併成一個類。你需要進行某種總體計算,例如,以便執行它使用的各種計算。

這似乎對我來說,你想要更多的東西沿着這些常規線路的情況:

// Each derived object only (apparently) needs two functions, so that's 
// what we'll define as the interface: 
struct base { 
    // equivalent to child1::A and B, and to child2::C and D: 
    virtual double A(std::vector<double> const &) = 0; 
    virtual double B(std::vector<double> const &) = 0; 
}; 

// Then a class for the overall computation, using (a pointer to) one of the 
// preceding:  
struct compute { 
    // equivalent to Parent::E(). 
    double E (base *b) { 
     b->A(vec); 
     Simplex(b->A(vec)); 
     b->B(vec); 
     Simplex(b->B(vec)); 
    }  
}; 

struct child1 : public base { 
    // Now each child provides two functions: 
    double A(std::vector<double> const &p) { 
     // do child1 computation A 
    } 
    double B(std::vector<double> const &p) { 
     // do child1 computation B 
    } 

    void F(compute *c) { 
     c->E(this); 
    }   
}; 

struct child2 : public base { 
    double A(std::vector<double> const &p) { 
     // do child2 computation A 
    } 
    double B(std::vector<double> const &p) { 
     // do child2 computation B 
    } 
    void G(compute *c) { 
     c->E(this); 
    }  
}; 

可以說,child1::F()child2::G()應該大概真的是在基類的單一功能,因爲它們都基本上是做同樣的事情。

如果可能指向任何child1child2對象的集合(所以你不知道,直到運行時一個特定的指針是否指child1child2),並且要進行相同的操作,前面的設計是合理的。

在另一方面,如果你知道在編譯時特定實例是否將是一個child1child2,你可以通過child1child2作爲模板參數,避免了虛函數的開銷:

// The class contained only a single function, so it can be just a function: 
template <class F> 
double compute(F const &f) { 
    f.A(vec); 
    Simplex(f.A(vec)); 
    f.B(vec); 
    Simplex(f.B(vec)); 
} 

class child1 { // no longer needs a common base class 
    double A(std::vector<double> const &); 
    double B(std::vector<double> const &); 
    void F() { compute(this); } 
}; 

class child2 { // no longer needs a common base class 
    double A(std::vector<double> const &); 
    double B(std::vector<double> const &); 
    void G() { compute(this); } 
}; 
+0

我更新了我的問題。我沒有讀完你正在做的一切,但我認爲我的更新與你的解決方案衝突。 –