2012-03-19 3 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. Есть ли способ сделать это?

Кроме того, мой код в порядке? Я имею в виду, как я могу его улучшить? Я совершенно новичок в ООП, и я хотел бы изучить некоторые хорошие практики.

Спасибо.

ответ

4

Идея концептуально сломана. Вы не можете сделать это; вам действительно нужны разные объекты.

В качестве альтернативы, если вы действительно хотите иметь несколько идентичных элементов, вы можете создать один элемент и создать для него несколько указателей и сохранить счет для количества активных элементов. A shared_ptr делает это, например.

При этом ваш код не должен использовать указатели вообще, это общий анти-шаблон в коде C++. Кроме того, ваш код, вероятно, не должен иметь сеттеров, обеспечивает надлежащий конструктор вместо:

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

Гораздо короче, проще и не Possiblity утечки памяти.

+0

Значит, использование сеттеров/геттеров не является хорошим? – FinalDestiny

+1

@FinalDestiny Это не так. Среди экспертов C++ существует консенсус в отношении того, что getters/seters используются в большинстве кодов. У них есть свое использование в некоторых кодах (например, трудно реализовать DAO без них), но большинство кода им не нужны. Они не подходят с объектно-ориентированным кодом, где каждый класс имеет одну конкретную цель. –

+0

Особенно «геттеры». Никакие геттеры не являются хорошими. Скажите объекту, что вы хотите. Сотрудничайте с другими объектами для выполнения работы. Например. 'printSpecs' может использовать объект' std :: ostream' для использования. Это упрощает тестирование, так как в настоящий момент вы неявно связаны с объектом 'cout'. –

0

Просто добавьте NumberOfItems в конструктор и уменьшите его в деструкторе.

+0

Да, но как я могу получить доступ к элементу 1, 2, 3, и т.д.? – FinalDestiny

+0

Вы хотите сохранить статический список элементов, а затем и счетчик. Добавьте каждый элемент в список в конструкторе и удалите его в деструкторе. –

+2

@FinalDestiny Классная мебель, не может действовать как предмет мебели и контейнер мебели в то же время. Вы смешиваете две разные концепции внутри одного объекта. Определите отдельный контейнер для мебели. – mloskot

2

Чтобы следить за количеством элементов, вы можете обновить количество элементов в конструкторе:

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

и декремента в деструкторе, если вы хотите:

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

Чтобы получить доступ к пункт по Id, вам нужно иметь дополнительный класс менеджера или использовать карту:

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

, который можно передать в качестве параметра конструктору и обновить его там:

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

И снаружи, вы можете просто получить элементы с:

Furniture* f = items[3]; 
+0

Да, но как мне показать цену/имя для пунктов 1, 2, 3? Как установить эти данные? – FinalDestiny

+0

@FinalDestiny обновленный ответ. –

+0

У вас нет. Если ваш класс представляет собой единый предмет мебели, тогда вы не можете поместить многих из них в него. У вас должен быть класс, который содержит «std :: vector » или что-то подобное, что будет хранить несколько предметов мебели. –

0

Храните экземпляры мебели в массиве или лучше в vector. Вы можете получить к ним доступ с помощью индекса или итератора. Поле NumberOfItems не относится к классу мебели, экземпляр мебели не должен знать о том, сколько предметов мебели есть в системе. Используйте метод size() от vector, чтобы получить количество предметов мебели.

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) вы забыли сопзЬ на добытчика ...

Смежные вопросы