簡體   English   中英

抽象類是否可以作為其他具體類的成員構成關系? C ++

[英]Can an abstract class be member of other concrete class as composition relationship ? c++

P是抽象類,我想使其成為A類的成員,而A類是普通的具體類。 如果可以,有可能嗎。 關系是組成謝謝您的幫助

由於P是抽象的,因此您永遠無法創建該類型的對象。 但是,您可以將指向P的指針存儲為類A的成員; 然后,此指針成員可以指向P (具體)子類的實例。

否。組成關系意味着Client類實際上包含類型AbstractClass的成員變量。

我假設您對“抽象類”的定義是具有至少一個純虛函數的類的常見定義。 這意味着它不能成為具體類的成員,因為該類不能被實例化。

您可以具有一個抽象類的引用或指針,該類包括一個為您管理生命周期的抽象類,例如組成關系,例如:

   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);

您不能創建抽象類的任何對象。 所以你不能這樣做。
但是,可以有一個指向抽象類的指針的類成員。

是一個代碼示例,以證明這一點:

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

class concrete
{
    abstract obj;

};
int main()
{
    return 0;
}

匯編:

prog.cpp:8:錯誤:無法聲明字段'concrete :: obj'為抽象類型'abstract'
prog.cpp:2:注意:因為以下虛擬函數在“抽象”中是純函數:
prog.cpp:3:注意:虛空抽象:: somethiing()

編譯樣本:

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

class concrete
{
    abstract *ptr;

};
int main()
{
    return 0;
}

您不能在另一個類中顯式實例化抽象類。 但是,您可以為抽象基類的純虛函數提供一個定義,該定義又可以在派生類中以與組合非常相似的方式調用。

有效的C ++編程(第二版)表明,抽象類中的純虛函數可以具有主體(定義)的原因是因為繼承類可以提供在其主體內調用純虛版本的函數的實現。

如果您有權使用該書,請參閱第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;
}

我了解這聽起來不對稱,但答案是否定的。 抽象類無法實例化,因此不能用作另一個類的成員。

這種不對稱是顯而易見的,因為您可以將抽象類用作基類,甚至必須實例化對象的基類子對象。 但是在這種情況下,該操作是允許的,並且簡單地將結果類自動變為抽象。

但是,合乎邏輯的原因是,在后一種情況下,您將能夠從這個新的抽象類派生出一個具體的類,而在前一種情況下,C ++語言語法將無法用一個對象來替換一個包含的對象類型。從該類型派生的類。

從某種意義上說,可以稍后在繼承層次結構中向下修改類的基礎子對象的類型,而固定成員子對象的類型是固定的。

您當然可以在對象中使用指向抽象類的指針或引用,因為在這種情況下,對象的實際類型將是具體的,並且僅在運行時才知道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM