1

これは、C++ の機能がどのように機能するかを明確にするための要求であり、可能かどうかという答えではありません。私が抱えていた問題を説明することから始めます。なぜなら、すぐに答えられるのは、それはあまり良いクラス設計ではないからです。

if ステートメントの保守不可能な塊になりつつあるクラスがあります。それをコンポジットに変換しようとしたとき、元のブロブの場合よりもディープ コピーを機能させることについて混乱し始めました。また、一般的な小さなオブジェクトの割り当ての問題もありました。そこで代わりに、BLOB をいくつかのクラスに分割し、コンパイラが元の BLOB に変換できるようにする方法を探し始めました。

次のコードでは、他のスタック オーバーフローの質問から、 super::get_x()infoo_bfoo_cinlinable がインライン化可能であることはわかっていますが、in がインライン化可能かどうかはわかりませsuper::get_z()foo_c。そして、最後のf.get_x()f.get_y()、およびへの呼び出しはf.get_z()、明示的でなく、サブクラスがあるかどうかがわからないため、仮想関数呼び出しになりますかfoo、それとも、実際にはそうではないため、インライン化できますか?

namespace PRIVATE {

class foo_a 
{
    int x, y, z;
public:
    foo_a(int X, int Y, int Z)
    {
        x = X; y = Y; z = Z;
    }
    virtual ~foo_a() { }

    virtual void update() { };

    virtual int get_x() const { return x; } 
    virtual int get_y() const { return y; }
    virtual int get_z() const { return z; }
};

class foo_b : public virtual foo_a 
{
typedef foo_a super;
    unsigned char c_0,c_1,c_2, mod;

public:
    foo_b(int X, int Y, int Z) : foo_a(X, Y, Z)
    {
        c_0 = c_1 = c_2 = mod = 0;
    }
    virtual ~foo_b() { }

    void activate_b()
    {
        c_2 = c_1;
        c_1 = c_0;
        c_0 = 5;

        mod = c_0? 1 + (c_1? 1 + (c_2? 1 : 0) : 0) : 0;
    }

    virtual void update()
    {
        super::update();

        if(c_0) { --c_0; mod = 1;
        if(c_1) { --c_1; mod = 2;
        if(c_2) { --c_2; mod = 3; }}};
    }
    virtual int get_x() const { return super::get_x() + mod; };
    virtual int get_y() const { return super::get_y() - mod; };
};

class foo_c : public virtual foo_b 
{
typedef foo_b super;
    bool active;

public:
    foo_c(int X, int Y, int Z) : foo_b(X, Y, Z)
    {
        active = false;
    }
    virtual ~foo_c() { }

    bool activate_c(bool X) { return (active = X); }

    virtual int get_x() const 
    { 
        int t = super::get_x();
        return active? t % 8 : t;
    }
    virtual int get_z() const 
    { 
        int t = super::get_z();
        return active? t % 8 : t;
    }
};

}

class foo : public virtual PRIVATE::foo_c 
{
public:
    foo(int X, int Y, int Z) : PRIVATE::foo_c(X, Y, Z) { }
    virtual ~foo() { }
};


int main(int argc, const char * argv[])
{
    foo * f = new foo(4, 6, 8);
    f->activate_b();
    f->get_x();
    f->get_y();
    f->get_z();

    delete f;

    return 0;
}
4

1 に答える 1