2012-03-20 7 views
4

Pは抽象クラスであり、通常の具象クラスであるクラスAのメンバーにしたいと考えています。もしそうなら、可能ですか?関係は構成です 助けてくれてありがとう抽象クラスは、他の具象クラスのメンバーで構成関係にすることはできますか? C++

+0

プライベートとして継承できますか? – DavidO

+0

あなたは自分でそれを試してみませんか? – Vijay

+0

@peter:どうですか?コンパイラのバグや未定義の動作に照らして、単に「試してみる」ことから学ぶことはほとんどありません。 – Mankarse

答えて

2

抽象クラスのオブジェクトを作成することはできません。そうすることはできません。
ただし、抽象クラスへのポインタであるクラスメンバを持つことができます。

Hereにそれを証明するためのコードサンプルです:

class abstract 
{ 
    virtual void somethiing() = 0; 
}; 

class concrete 
{ 
    abstract obj; 

}; 
int main() 
{ 
    return 0; 
} 

編集:

prog.cpp:8: error: cannot declare field ‘concrete::obj’ to be of abstract type ‘abstract’
prog.cpp:2: note: because the following virtual functions are pure within ‘abstract’:
prog.cpp:3: note: virtual void abstract::somethiing()

Compilable sample:

class abstract 
{ 
    virtual void somethiing() = 0; 
}; 

class concrete 
{ 
    abstract *ptr; 

}; 
int main() 
{ 
    return 0; 
} 
5

Pは抽象であるため、決してそのタイプのオブジェクトを作成することはできません。ただし、クラスAのメンバとしてPへのポインタを格納できます。このポインター・メンバーは、Pという(具象的な)サブクラスのインスタンスを指すことができます。

3

いいえ。構成関係は、class Clientに実際にAbstractClass型のメンバー変数が含まれていることを示しています。

"抽象クラス"の定義は、少なくとも1つの純粋仮想関数を持つクラスの共通のものと仮定しています。つまり、そのクラスはインスタンス化できないため、具体クラスのメンバーになれません。

あなたは例えば、多くの組成の関係のように寿命があなたのために管理されているものを含む抽象クラスへの参照やポインタを持つことができます。

class Client { 
    public: 
     Client(AbstractClass* adopted) : ownedAbstract(adopted) {} 
    ... 
    std::shared_ptr<AbstractClass> ownedAbstract; 

    }; 

    class AbstractClass{ 
    public: 
     virtual ~AbstractClass()=0; // virtual dtor needed so can delete AbstractClass*  
    };  

    class AbstractSubclass : public AbstractClass{ 
    public: 
     virtual ~AbstractSubclass(); 
    }; 


    Client fred(new AbstractSubclass); 
0

あなたが別のクラスの中に明示的に抽象クラスをインスタンス化しないことがあります。しかし、抽象基底クラスの純粋な仮想関数に定義を与えることができます。この定義は、派生クラスの中で、多くのような構成を感じるように呼び出すことができます。

有効なC++プログラミング(第2版)は、抽象クラスの純粋仮想関数がbody(定義)を持つことができる理由は、継承クラスがその本体内の純粋仮想バージョンを呼び出す関数。

あなたが本へのアクセス権を持っている場合は、項目36

を参照してくださいここで私は一緒に石畳例です。抽象クラスからインタフェースを継承し、その実装を使用して、派生クラスの関数の定義の実装を構成することによって、オブジェクト構成の形式をどのように実現できるかを示します。

#include <iostream> 

class P { 
    public: 
    virtual void say_hello() = 0; 
}; 

void P::say_hello() { std::cout << "Hello world!" << std::endl; } 

class A :public P { 
    public: 
    void say_hello() { P::say_hello(); } 
}; 

int main() { 
    A x; 
    x.say_hello(); 
    return 0; 
} 

結果は、そのクラスAの「say_hello」は同じ名前で関数のPの純粋仮想バージョンを呼び出すになります。 Aの "say_hello()"を呼び出すと、 "Hello world"という文字列が出力されます。

抽象クラスのパブリックおよび保護されたメンバーデータは、派生クラスでも使用できます。

#include <iostream> 
#include <string> 

using namespace std; 

class P { 
    public: 
    P() { audience = "world"; } 
    virtual void say_hello() = 0; 
    protected: 
    string audience; 
}; 

void P::say_hello() { cout << "Hello " << audience << "!" << endl; } 

class A :public P { 
    public: 
    void say_hello() { P::say_hello(); } 
    void say_goodbye() { cout << "Goodbye " << audience << "." << endl; } 

}; 

int main() { 
    A x; 
    x.say_hello(); 
    x.say_goodbye(); 
    return 0; 
} 
0

私はこれが非対称的だと思いますが、答えはノーです。抽象クラスはインスタンス化できないため、別のクラスのメンバーとして使用することはできません。

抽象クラスをベースとして使用できるため、オブジェクトの基本サブオブジェクトさえもインスタンス化する必要があるため、非対称性が明白です。この場合、操作は許可され、結果として得られるクラスは自動的に抽象クラスになります。

ただし論理的な理由は、この最後のケースでは、この新しい抽象クラスから具体的なクラスを派生させることができますが、前者の場合は、後でC++言語構文を使用して、その型から派生したクラスのオブジェクトを持つ型。

ある意味では、クラスの/ a基本サブオブジェクトのタイプは、継承階層で後で変更できますが、通常のメンバサブオブジェクトのタイプは固定されています。

オブジェクト内の抽象クラスへのポインタまたは参照を使用できます。この場合、オブジェクトの実際の型は具体的であり、実行時にのみ認識されるからです。

関連する問題