2015-08-15 164 views
0

我有一個派生自「公司」的抽象基類「Company」和2個子類「notForProfit」和「forProfit」。兩個子類都有成員變量「name」和「dateFormed」。是否有可能在「公司」中定義這兩個成員變量,並讓2個子類繼承「Name」和「DateFormed」以在其構造函數中使用?抽象基類成員變量

+0

它們可以位於基礎中,可以在派生類中訪問,但不能直接在初始化列表中;您可以通過名稱構造基類,因此請爲基類提供一個構造函數,以便爲這些成員提供參數。不管這是否是一個好主意,要在類中定義接口的數據,我不確定。另外,你可能會在'protected'的奇怪世界中結束。 – BoBTFish

+0

你需要問的最大問題是:'ForProfit'和'NotForProfit'子類有什麼區別?你需要使用編譯時類型檢查來區分兩者嗎?他們有其他不同的數據成員嗎?如果他們不這樣做,你可能會想簡單地在'Company'類中添加一個'bool forProfit'成員,而不需要子類型。 –

+0

或使用純粹的虛擬方法來強制兩個子類來實現這兩個成員的獲取者 – user3528438

回答

2

一個非盈利的公司是一個企業,一個以營利爲目的的公司是一家公司,但公司不是一個名稱,它不是形成一個日期,而不是一個公司有一個名字和組建日期。

「是」關係是繼承。 「有一個」關係是聚合。

如果兩個公司共享相同的成員,那麼這些應該是在基類中,因爲代碼重用是繼承的主要內容(除了多態性)

class Company { 
protected: 
    Company(QString n, QDate df) : name(n), dateFormed(df) { } // protected constructor, can't create a Company instance 
    QString name; // protected data members, cannot be accidentally changed 
    QDate dateFormed; 
public: 
    virtual ~Company() {} // you always need a virtual destructor for polymorphism 
    virtual void info() = 0; // abstract method, must be implemented in order to instantiate derived classes  
}; 

class NonProfit : public Company { 
public: 
    NonProfit(QString n, QDate df) : Company(n, df) { } 
    void info() { qDebug() << "Non-profit company" << name << "formed on" << dateFormed; } 
}; 

class ForProfit : public Company { 
public: 
    ForProfit(QString n, QDate df) : Company(n, df) { } 
    void info() { qDebug() << "For-profit company" << name << "formed on" << dateFormed; } 
}; 

和使用一個:

Company cp("some company", QDateTime::currentDateTime().date()); // won't work 
NonProfit np("some company", QDateTime::currentDateTime().date()); 
np.info(); // Non-profit company "some company" formed on 2015-08-15 

多態性在行動:

Company * c1 = new NonProfit("some company", QDateTime::currentDateTime().date()); 
Company * c2 = new ForProfit("some company", QDateTime::currentDateTime().date()); 
c1->info(); // Non-profit company "some company" formed on 2015-08-15 
c2->info(); // For-profit company "some company" formed on 2015-08-15 

還要注意,即使去rive類沒有聲明的虛析構函數,info沒有明確的虛函數,只要基類有一個聲明的虛析構函數,C++就會自動生成虛析構函數,而且信息也會隱式地虛擬化,有些人更喜歡編寫方法作爲派生類中的虛擬以清楚起見,但是一旦在基類中虛擬化,方法也將在派生類中隱式虛擬。

+0

謝謝@ddriver,這是一個非常清楚/可以理解的解釋。 forProfit和notForprofit都有一些獨特的成員,所以我可以像這樣初始化forProfit forProfit :: forProfit(QString name,QDate date,int employees):Company(name,date),m_employees(employees){}? – user2094257

+0

@ user2094257 - 是的,這是要走的路。當然,如果所有公司都有員工,那麼也應該進入基礎班。 – dtech

1

是的,基礎和派生之間的關係是「是一個」,基類有一切,派生類有。

代碼片段:

// derived classes 
#include <iostream> 
using namespace std; 

class Polygon 
{ 
protected: 
int width, height; 

public: 
    void set_values (int a, int b) 
    { 
     width=a; 
     height=b; 
    } 
}; 

class Rectangle: public Polygon 
{ 
public: 
    int area() 
    { 
     return width * height; 
    } 
}; 

class Triangle: public Polygon 
{ 
public: 
    int area() 
    { 
     return width * height/2; 
    } 
}; 
+0

我是nervus,因爲我的第一個anser,我需要up-vots聲望,我從一些cpp站點複製:) – Yael

+0

那麼,這是一個不好的例子,多邊形和三角形都不是由寬度和高度來定義的。這隻適用於矩形。你應該已經實施了OP所詢問的內容。 – dtech

+0

無論如何我的答案,回答問題 – Yael