2016-08-02 11 views
2

コピー代入演算子のデフォルト機能を使用したいが、操作の一部としていくつかの追加のタスクを実行したい。オーバーロードされたコピー代入演算子からC++のデフォルトのコピー代入演算子を呼び出す

class Test 
{ 
    void operator=(Test& that) 
    { 
     *this = that; //do the default copy operation 
     this->foo() //perform some other tasks 
    } 
}; 

これは簡単にコピー()関数を作成することによって行うことができるが、「=」操作の清浄度を維持するためにいいだろう。だから、基本的なフォームは次のようになります。

答えて

3

あなたは

// Fill this class with your implementation. 
class ClsImpl { 
    // some complicated class 
protected: 
    ~ClsImpl() = default; 
}; 

class Cls : public ClsImpl { 
public: 
    Cls& operator=(const Cls& other) { 
    if (this == &other) { return *this; } 
    // assign using the base class's operator= 
    ClsImpl::operator=(other); // default operator= in ClsImpl 
    this->foo(); // perform some other task 
    return *this; 
    } 
}; 
+2

は、なぜあなただ​​けではなく、 'ClsImpl ::演算子=(その他)を介して明示的に呼び出すの基本クラスの実装を呼び出す強制的に' static_cast'を使用しています; '。 'ClsImpl'がコピーアサイン機能を委譲する単なる手段であれば、暗黙のコンバージョンを防ぎ、スライシングのリスクを導入するためにプライベート継承を使うべきでしょう。 –

+1

@Captain彼らは同じことになりますが、キャストを省略することは利益です、私は同意します。プライベート継承は、基本クラスのメンバ関数のすべてを公開するために、大量の 'using'宣言を必要としないようであれば素晴らしいでしょう。 –

+0

ええ、多くの 'using'ステートメントは吸うでしょう。基本クラスでコピーコンストラクタとコピー代入演算子を保護することは、とにかくスライシングを処理するでしょう。 –

0

サブクラスからベースoperator=にベース実装クラスとデリゲートを使用することができます一つの方法は、ポストコピーロジックを提供するために、派生クラスから再び導出することです。

#include <iostream> 


// a wrapper class to provide custom copy actions 

template<class Base> 
struct CopyActions : Base 
{ 
    using base_class = Base; 
    using CopyActions::base_class::base_class; 

    // copy operator will call the base and then perform custom action 

    CopyActions& operator=(const CopyActions& r) { 
     base_class::operator=(r); 
     onCustomCopy(r, *this); 
     return *this; 
    } 
}; 

// a class to notify us when a copy takes place, without having to write 
// custom copy operators 
struct copy_sentinel 
{ 
    copy_sentinel operator=(const copy_sentinel&) { 
     std::cout << "copying " << name << '\n'; 
     return *this; 
    } 
    const char* name; 
}; 


int test_count = 0; 

// a model base class 
struct MyBase 
{ 
    int base_count = test_count++; 
    copy_sentinel base_s { "MyBase" }; 
}; 

// a model derived class containing only logic 
struct MyDerived : MyBase 
{ 
    int derived_count = test_count++; 
    copy_sentinel base_s { "MyDerived" }; 
}; 

// a custom copy action (free function) 
void onCustomCopy(const MyDerived& from, MyDerived& to) 
{ 
    std::cout << "custom copy action\n"; 
} 

// our derived class with custom copy actions 
using SuperDerived = CopyActions<MyDerived>; 

// test 
int main() 
{ 
    SuperDerived a; // 0, 1 
    SuperDerived b; // 2, 3 

    // prove initial values 
    std::cout << a.base_count << ", " << a.derived_count << std::endl; 

    // perform copy and report actions 
    a = b; 

    // prove a copy occurred 
    std::cout << a.base_count << ", " << a.derived_count << std::endl; 
} 

期待される結果:

0, 1 
copying MyBase 
copying MyDerived 
custom copy action 
2, 3 
関連する問題