2016-05-20 10 views
2
#include <iostream> 
using namespace std; 

class A{ 
private: 
    double price; 
public: 
    A(double p):price(p){ 
    } 
    virtual double abstractExample() = 0; 
    A* operator++(int dummy){ 
    this->price = this->price + 1; 
    return this; 
    } 
    virtual ~A(){ 
    } 
    void print(){ 
    cout << price << endl; 
    } 
}; 

class B : public A { 
    public: 
    B(int p): A(p){ 
    } 
    double abstractExample(){ 
     return 1; 
    } 
}; 

int main(){ 
    B* b = new B(5); 
    b->print(); 
    b++->print(); 

    return 0; 
} 

したがって、私はこの抽象クラスAを持っています。++演算子をオーバーロードしたいと思います。通常はA &演算子++(int dummy)を書くだけですが、この場合は抽象クラスなのでオブジェクトへのポインタを返す必要があります。各継承クラスに別々のコードを記述することなくこれを行う方法はありますか?抽象クラスにおけるインクリメンタル演算子のオーバーロードC++

これは5、5の代わりに、5、6

+0

**変更前に**値を返すことが期待されているので、後置演算子のあなたの実装は、正しくありません。 – SergeyA

+0

@SergeyA _ "後置演算子の実装が正しくありません" _はい、そうです。しかし、抽象クラスを実際どのように扱うことができるのでしょうか?それは良い質問です。 –

+2

@πάνταῥεῖ[this](http://stackoverflow.com/questions/18172858/c-abstract-base-class-postfix-operator)はCRTPを使用しようとしています – NathanOliver

答えて

0

の入力を与えるが、私はこの場合には、それは抽象クラスなので、オブジェクトへのポインタを返すことがあります。

いいえ。実際には参照がより良いです。あなたが価値あるものを返さない限り、スライスすることはありません。

+0

postfix増分が正しく実装されていない。 – SergeyA

+0

つまり、 'operator ++'から返されたオブジェクトは 'this'なので、' this'は 'this'を使って安全に' * this'を参照することができ、スライスは起こりません。返される参照の存続期間は、 'A'由来オブジェクトの存続期間です。 – Kupiakos

+0

ありがとう、それは今の魅力のように動作します。 – xxm0dxx

3

ポリモフィックな実装を非ポリモーフィックなラッパーでラップしない限り、算術演算子は多型のクラスでうまく動かない。コード内

コメントは、あなたのベースクラスへの追加を説明します。

#include <iostream> 
#include <memory> 

using namespace std; 

class A{ 
private: 
    double price; 
public: 
    A(double p):price(p){ 
    } 
    virtual double abstractExample() = 0; 

    void increment() 
    { 
    this->price = this->price + 1; 
    } 

    // see below. clone in base must be abstract if the base class 
    // is abstract. (abstractExample is pure so that's that) 
    virtual std::unique_ptr<A> clone() const =0; 

    virtual ~A(){ 
    } 

    void print(){ 
    cout << price << endl; 
    } 
}; 

class B : public A { 
    public: 
    B(int p): A(p){ 
    } 
    double abstractExample(){ 
     return 1; 
    } 

    std::unique_ptr<A> clone() const override 
    { 
    return std::make_unique<B>(*this); 
    } 

}; 

struct AB 
{ 
    AB(std::unique_ptr<A> p) : _ptr(std::move(p)) {} 

    // pre-increment is easy 
    AB& operator++() { 
    _ptr->increment(); 
    } 

    // post-increment is trickier. it implies clonability. 
    AB operator++(int) { 
    AB tmp(_ptr->clone()); 
    _ptr->increment(); 
    return tmp; 
    } 

    void print() { 
    _ptr->print(); 
    } 

    std::unique_ptr<A> _ptr; 
}; 

int main(){ 
    AB b(std::make_unique<B>(5)); 
    b.print(); 

    // pre-increment 
    (++b).print(); 

    // post-incrememnt will involve a clone. 
    (b++).print(); 

    return 0; 
} 
関連する問題