2012-03-19 127 views
-2

我有類傢俱:如何用C++中的一個類創建多個項目?

Furniture.h:

#include <iostream> 
#include <string> 
using namespace std; 

class Furniture { 
public: 
    Furniture(); 
    ~Furniture(); 
    void setname(string name); 
    void setprice(double price); 
    double getprice(); 
    string getname(); 
    virtual void printSpecs(); 
private: 
    string name; 
    double price; 
protected: 
    static int NumberOfItems; 
    int Id; 

}; 

furniture.cpp:

#include "furniture.h" 

Furniture::Furniture() { 
} 
Furniture::~Furniture() { 
} 
void Furniture::setname(string name) { 
    this->name = name; 
} 
string Furniture::getname() 
{ 
    return this->name; 
} 
void Furniture::setprice(double price) { 
    this->price = price; 
} 
double Furniture::getprice() { 
    return this->price; 
} 
void Furniture::printSpecs() { 
    cout<<"Price: "<<this->price<<endl; 
    cout<<"Name: "<<this->name<<endl; 
} 

int main() { 
    Furniture *model = new Furniture(); 
    model->setname("FinalDestiny"); 
    model->setprice(149.99); 
    model->printSpecs(); 
    delete model; 
} 

一切工作正常,但我想補充相同類別的多個傢俱物品並只更新NumberOfItems。有沒有辦法做到這一點?

另外,我的代碼好嗎?我的意思是,我該如何改進它?我對OOP很陌生,我想學習一些好的做法。

謝謝。

回答

4

的想法是概念上打破了。你不能這樣做;你真的需要不同的對象。或者,如果您確實想要擁有多個相同的項目,則可以創建一個項目併爲其創建多個指針,併爲活動項目的數量保留一個單獨的個計數。 A shared_ptr就是這樣做的。

也就是說,你的代碼根本不應該使用指針,這是C++代碼中常見的反模式。此外,你的代碼可能不應該制定者,提供合適的構造來代替:

int main() { 
    Furniture model("FinalDestiny", 149.99); 
    model.printSpecs(); 
} 

更短,更簡單,沒有內存泄漏的方法可行。

+0

那麼setter/getters的用法不好? – FinalDestiny 2012-03-19 11:03:29

+1

@FinalDestiny不是。 C++專家一致認爲,大多數代碼中getter/setter被過度使用。他們確實在某些代碼中使用它(例如,很難在沒有它們的情況下實現DAO),但大多數代碼並不需要它們。它們不適合面向對象的代碼,每個類都有一個特定的目的。 – 2012-03-19 11:05:59

+0

尤其是'getters'。沒有獲得者是好的。告訴物體做你想做的事。與其他對象協作完成工作。例如。 'printSpecs'可以使用'std :: ostream'對象來使用。這使得測試更容易,因爲目前,您隱式地耦合到「cout」對象。 – 2012-03-19 11:31:47

0

只是在構造函數中增加NumberOfItems,並在析構函數中遞減它。

+0

呀,但我如何訪問項目1,2,3,等等? – FinalDestiny 2012-03-19 10:57:20

+0

你想保留一個項目的靜態列表,然後,以及一個計數器。將每個項目添加到構造函數中的列表中,並在析構函數中將其刪除。 – 2012-03-19 10:59:45

+2

@FinalDestiny類別的傢俱,不能同時作爲一件傢俱和一個傢俱的容器。您在單個實體中混合了兩個不同的概念,爲傢俱定義單獨的容器。 – mloskot 2012-03-19 11:02:16

2

爲了保持項目數的軌道,你可以更新項目的構造函數中的號碼:如果你想在析構函數

Furniture::Furniture() { 
    Id = NumberOfItems++; 
} 

和遞減:

Furniture::~Furniture() { 
    NumberOfItems--; 
} 

要訪問您需要有一個額外的經理類或使用地圖:

std::map<int,Furniture*> items; 

,你可以通過爲參數的構造有更新:

Furniture::Furniture(std::map& items) { 
    Id = NumberOfItems++; 
    items[Id] = this; 
} 

,外,你可以簡單地檢索與物品:

Furniture* f = items[3]; 
+0

是的,但是如何顯示項目1,2,3的價格/名稱?我如何設置這些細節? – FinalDestiny 2012-03-19 10:58:59

+0

@FinalDestiny更新了答案。 – 2012-03-19 11:01:36

+0

你沒有。如果你的班級代表一件傢俱,那麼你不能把它們中的許多放進去。你應該有一個包含'std :: vector '或類似的東西的類來存儲多件傢俱。 – 2012-03-19 11:02:16

0

將傢俱實例存儲在一個陣列中或更好的vector中。您可以使用索引或迭代器訪問它們。 NumberOfItems字段不屬於傢俱類,傢俱實例不應該知道系統中有多少傢俱。使用vector中的size()方法獲取傢俱物品數量。

2

我會以這種方式

#include <iostream> 
#include <string> 
using namespace std; 

class Furniture { 
public: 
    Furniture(string name = "", double price = 0) 
     : name(name), price(price), Id(NumberOfItems++) 
    {} 
    Furniture(const Furniture &f) 
     : name(f.getname()), price(f.getprice()), Id(NumberOfItems++) 
    {} 

    void setname(string name) { this->name = name; } 
    void setprice(double price) { this->price = price; } 
    double getprice() const { return price; } 
    string getname() const { return name; } 

    virtual void printSpecs() {} 

private: 
    string name; 
    double price; 

protected: 
    static int NumberOfItems; 
    int Id; 
}; 
int Furniture::NumberOfItems; 

int main_furniture(int, char **) 
{ 
    Furniture a("product 1", 100); 
    Furniture x(a), y(a), z(a); 
} 

我只是內聯,以簡化編寫。什麼是有趣的,你應該是拷貝構造函數實施,以及(OT)你忘記上吸氣劑常量 ...

相關問題