0

基本クラスの非仮想関数で、派生クラスに実装されている基本クラスの仮想関数を呼び出すのは正しいですか。何かのようなもの

class A
{
 virtual void func1() = 0;

 void func2()
 {
   func1();
 }
};

class B : public A
{
 virtual void func1()
 {
   //do something here;
 }
};

int main()
{
 A* obj = new B;
 obj->func2();
 return 0;
}
4

4 に答える 4

2

はい、これで動作します。自分でやってみましたか?

于 2013-03-13T17:28:51.760 に答える
2

これは問題を解決するためのよく知られた有効な方法であるだけでなく、func2インライン化されている場合は、内部関数を直接呼び出す場合に比べて余分なオーバーヘッドがないことを意味します。func1明らかに、内部で何らかの処理を行い、途中または最後に呼び出すことが全体の目的であるfunc2場合もありますが、その余分な作業が最小限である場合、「追加機能レイヤー」はおそらく完全に消えます。

于 2013-03-13T17:43:16.207 に答える
1

はい。この手法は、演算子の実装に仮想関数の動作が必要な場合に使用されます。仮想(または抽象)関数の観点から演算子を定義し、特殊化によってその関数の実装方法を決定します。

例:

class base
{
// yada yada yada
    base& operator=(const base& other) { return assign(other); }
protected:
    virtual base& assign(const base& other) = 0; // specializations will decide
                                                 //  what assignment means
};

編集:このテクニックのもう1つの用途は、クラスの特殊化によって、より複雑な操作の一部のみを制御できるようにすることです。

class database
{
public:
    void execute(const std::string& query)
    {
        begin_transaction(); // in practice, this should be RAII
        connection_.execute(query);
        end_transaction();
    }
protected:
    virtual void begin_transaction() = 0;
    virtual void end_transaction() = 0;
private:
    whatever &connection_;
};

データベースの専門分野では、仮想mysql_database::begin_transactionの実装はとは異なりますsqlite_database::begin_transaction

于 2013-03-13T17:33:39.817 に答える
1

はい、大丈夫です。これにより、基本クラスで共通のフローを提供できます。その詳細は、その子に特化されています。

テンプレート メソッドを参照してください。

于 2013-03-13T17:29:52.493 に答える