2017-01-03 2 views
1

抽象クラスには内部仮想関数があります。 抽象クラスは後で実装する内部仮想クラスを持つことができますか?内部抽象メンバクラスをC++で実装するにはどうすればよいですか?

私は次のことを試してみました:

#include <bits/stdc++.h> 
using namespace std; 

class C1 { 
    public: 
     class Child { 
      int tmp; 
      virtual int getint() = 0; 
     }; 
    virtual Child getChild() = 0; 
}; 

class C2: public C1 { 
    public: 
     class Child { 
      int getint() 
      { 
       return 10; 
      } 
     } c; 
    Child getChild() 
    { 
     return c; 
    } 
}; 

int main() { return 0; } 

子供は、派生クラスでオーバーライドされる抽象クラスです。そして、私は実装が願っていますは、関数を定義するために使用することができます。

はしかし、私はエラーを得た:

invalid abstract return type for member function 'virtual C1::Child C1::getChild()'

は、私はちょうど仮想関数を実装するように、派生クラスで内部抽象クラスを実装することができませんか?

+0

これは、内部クラスとは関係ありません。あなたはあなたの例を大幅に単純化することができます。ここには[mcve]があります: 'struct foo {virtual stuff()= 0; }; foo make_foo(); '。 – juanchopanza

+0

抽象オブジェクトを値として返すことはできません。そうすれば、 'pure virtual'関数の実装が欠落しているので、クライアントはどのようにそれを使用できますか?ただし、そのようなオブジェクトへのポインタを返すことはできます。さらに:あなたの例では '子'は抽象ではありません。あなたの問題を誰かが理解できないかもしれないので、それを編集してください。 –

+0

@MichałWalenciakクライアントは、抽象クラスで定義された仮想関数を呼び出します。 –

答えて

2

このコードでは、class C1::Childclass C2::Childには継承関係がありません。したがって、彼らはまったく無関係のクラスです。継承を関連付ける場合でも、getChild()Child(値)を返すことはできません。 Child&(参照)ま​​たはChild*(ポインタ)のいずれかを返して、有効なvirtualメソッドを作成し、共分散とすることができます。 C++ virtual function return type

このようなエラーは、C++ 11で利用可能なoverride指定子を使用すると簡単にキャッチされます。

あなたが達成しようとしているかの正確な状況を知らなくても、可能なコードは次のようになります。

class C1 { 
    // ... same 
    virtual Child& getChild() = 0; 
    //  ^^^^^^ reference 
}; 

class C2 : public C1 { 
//   ^^^^^^ did you miss this? 
public: 
    class Child : public C1::Child { 
    //     ^^^^^^^^^ inheritance 
    int getint() override { return 10; } 
    } c; 
    Child& getChild() override { return c; } 
}; 

また、あなたの下の文では、混乱を招くようだ:

"Child is a abstract class, which will be implemented later,"

のようにvirtualメソッドでは、クラスにこのような実行時関係がありません。クラスの文脈で「後で実行」の
最高の意味がある - など、包含するクラスの本体の外にそれを実装する:あなたは混乱のものであるように見えるあなたのポストから

class Outer { public: class Inner; }; 
// ... 
class Outer::Inner { ... }; 
+0

仮想関数と抽象クラスとは異なる扱いですか?私は仮想関数を呼び出すことはできますが、抽象クラスは使用できません。 –

+1

@ ZehuiLin、私はあなたの正確なQnについて不明です。しかし、抽象クラスは、少なくとも1つの純粋な 'virtual'メソッドが本体内にあるクラスです。 'virtual'メソッドは、基本クラス参照またはポインタを使用して呼び出されます。基本クラスが抽象クラスの場合、そのオブジェクトを持つことはできません。あなたに不明な点がある場合は、いくつか例を挙げることをお勧めします。抽象クラスの詳細については、これを参照してください:[抽象クラスとC++のインタフェース](http://stackoverflow.com/q/12854778/514235) – iammilind

0

。私はあなたが抽象クラスで再読み込みを取得し、簡単な例をいくつか試してみることをお勧めします。 (あなたの例ではvirtual int getint() = 0;

Child is a abstract class, which will be implemented later, And I hope the implemented Child can be used to define a function.

純粋仮想メソッドは、「後で」に実装されることを意味しません。派生クラスのオーバーライドメソッドによって実装されることを意図しています。

など。あなたは

class Child { 
    virtual int getint() = 0; 
}; 

を持っている場合は、後で

class Child { 
    virtual int getint() { return 10; } 
}; 

int Child::getint() { return 10; } 

を行うことはできません。あなたは何ができるか

は次のとおりです。理論的に

class Derived : public Child 
{ 
    int getint() override { return 10; } 
}; 
1

Abstract ClassesInterfacesを作成するために使用されています。 Interfacesを使用すると、クライアントは必要な機能を要求します。 Interfacesを定義/実装することにより、サーバーはクライアントの機能を満たします。 Interface/Abstract Classは、単にクライアントとサーバーの間の要件/合意の青写真です。 Interface/Abstract Classを実装するか、機能要件を満たすクラスをインスタンス化することができます。だから同じInterface/Abstract Classの多くの実装があります。異なる時点でシームレスに同じInterface/Abstract Classのこれらの異なる実装にアクセスするには、一般化された方法が必要です。そして、この一般化された方法は、を介して、基礎となるInterface\Abstract Classになります。

C1::ChildのコードはAbstract Class or Interfaceです。

したがって、C1::getChild()Interface/Abstract C1::Childの実装を返すことができます。しかし、上記の理論的説明の通りにInterface/Abstract C1::Childのインスタンスを返すことはできません。したがって、エラー。 C1::getChild()を宣言する 適切な方法は、次のようになります。

  • virtual C1::Child* getChild() = 0;あるいはまた
  • virtual C1::Child& getChild() = 0;

C1::Childは単にnamespace C1内部classとして見ることができ、classnamespaceの種類がいくつかでもあるので、制限。

関連する問題