2016-05-26 10 views
1

私は別のクラスで構成されたBaseクラスを持っています。 Baseクラスから継承した場合、Componentクラスに機能を追加することは可能ですか(Baseコードを変更することはできません)私は基本的に 'Derived :: Component :: foo'関数が必要です。派生クラス内でネストされたクラスメンバ関数を定義できません

エラー:メンバ関数 '派生' 内の '基本::コンポーネント:: foo' で

+0

これは、どのような状況でも無効です。クラス宣言で関数を定義する必要があります。 – pingul

+0

あるクラスのメンバーを別のクラスのメンバーとして定義することはできません。 – kfsone

+0

Derived :: Component :: fooメンバ関数を追加する方法はありますか? – ruslank

答えて

1

を定義することはできませんあなたが宣言する必要が

#include <iostream> 

class Base 
{ 
    public: 
     void Print() { std::cout << c.data; } 

     class Component 
     { 
      public: 
       int data; 
     }; 
     Component c; 
}; 

class Derived : public Base 
{ 
    private: 
     void Component::foo(int value) 
     { 
      this->data = value; 
     } 
    public: 
     void bar(int value) 
     { 
      this->c.foo(value); 
     } 
    }; 

int main() { 
    Derived d; 
    d.bar(4); 
    d.Print(); 
} 

このコードは、Ubuntuの上のG ++ 4.8の下で、次のエラーが発生しますComponentクラスのfoo機能です。そしてComponent自体の内部にそれを定義します。

#include <iostream> 

class Base 
{ 
public: 
    void Print() { std::cout << c.data; } 

    class Component 
    { 
    public: 
     int data; 
     void foo(int value) 
     { 
      data = value; 
     } 
    }; 

    Component c; 
}; 

class Derived : public Base 
{ 
private: 
public: 
    void bar(int value) 
    { 
     c.foo(value); 
    } 
}; 

int main() { 
    Derived d; 
    d.bar(4); 
    d.Print(); 
} 

またはクラスのすべての外:問題の実際の基底クラスがどのように見える、あなたが試みることができる方法に応じて

#include <iostream> 

class Base 
{ 
public: 
    void Print() { std::cout << c.data; } 

    class Component 
    { 
    public: 
     int data; 
     void foo(int value); 
    }; 

    Component c; 
}; 

void Base::Component::foo(int value) 
{ 
    data = value; 
} 

class Derived : public Base 
{ 
private: 
public: 
    void bar(int value) 
    { 
     c.foo(value); 
    } 
}; 

int main() { 
    Derived d; 
    d.bar(4); 
    d.Print(); 
} 
+0

Baseのソースコードにアクセスできない場合、これは動作しますか? – ruslank

+0

'Base'を変更して' foo() '宣言を' Component'に追加できない場合は、noを返します。派生クラスは、基本的にネストされたクラスにメンバーを追加することはできず、宣言されていないメソッドの実装を定義することはできません。 –

2

[..] add functionality [..] (assumming you can't modify the Base code) [..]

Componentの簡単なサブクラスで取得する:

/* using struct to have public accessibility */ 
struct Base { 
    struct Component { 
    int data; 
    virtual ~Component() {} // ABSOLUTELY NECESSARY 
    }; 
    std::unique_ptr<Component> component; // ABSOLUTELY NECESSARY 

    void print(void) { 
    std::cout << component->data << endl; 
    } 
}; 

/* The decorated component, with the additional functionality */ 
struct DecoratedComponent : public Base::Component { 
    void set(int d) { 
    data = d; 
    } 
}; 

次に、aあなたの装飾されたコンポーネントを渡す必要があることに注意してください(注:保存する状態がある場合、デコレータパターンを実際に使用するように、Componentインスタンスを装飾されたコンポーネントクラスにラップすることもできます)。

Base the_base; 
auto the_component = std::make_unique<DecoratedComponent>(); 
// Inject the decorated component 
the_base.component = the_component; 
the_component.set(42); 
the_base.print(); // 42 

ベースが、それはコンポーネントです/アクセスを保存するための参照やポインタのいくつかの並べ替えのいずれかを使用している場合にのみ動作します。さらに、ベースがコンポーネントのライフタイムを管理している場合、Componentには仮想デストラクタが必要です。

+0

このアプローチは、コンポーネントの機能を拡張するのに役立ちます。理想的には、「DecoratedComponent」と他の新しいBaseメソッドをDerivedクラスに組み合わせることができます。それを行うためのきれいな方法はありますか? – ruslank

+0

@ruslankええと... 'Base'もサブクラス化しますか?つまり、 'DecoratedComponent'(宣言)をそのサブクラスのメンバにすることができます。 –

関連する問題