#c #oop #design-patterns #singleton
#c #ооп #шаблоны проектирования #singleton
Вопрос:
Мне нужно создать простое приложение, например корзину покупок.
main.cpp
int main()
{
Cart cart;
// add items
cart.addItem("Shirt", ItemType:Clothing);
cart.addItem("Xbox", ItemType::Entertainment);
cart.addItem("Bowl", ItemType::Cooking);
// print item
cart.printItems();
Item::destroy();
}
Item.h
enum ItemType
{
Cooking,
Clothing,
Entertainment
};
class Item
{
private:
Item(const std::stringamp; name, const ItemTypeamp; itemType);
static Item* m_instance;
std::string m_name;
ItemType m_itemType;
public:
static Item *getInstance(const std::stringamp; name, const ItemTypeamp; itemType);
static void destroy();
const std::stringamp; getName() const;
const ItemTypeamp; getItemType() const;
void print() const;
};
Item.cpp
Item* Item::m_instance = nullptr;
Item::Item(const std::stringamp; name, const ItemTypeamp; itemType)
{
m_name = name;
m_itemType = itemType;
}
Item* Item::getInstance(const std::stringamp; name, const ItemTypeamp; itemType)
{
if (!m_instance) {
m_instance = new Item(name, itemType);
}
return m_instance;
}
void Item::destroy()
{
delete m_instance;
m_instance = nullptr;
}
void Item::print() const
{
std::cout << "Item name: " << m_name << std::endl;
}
Cart.h
class Cart
{
public:
Cart();
~Cart();
void addItem(const std::stringamp; name, const ItemTypeamp; itemType);
void printItems();
private:
std::vector<Item*> m_itemList = {};
};
Cart.cpp
void Cart::addItem(const std::stringamp; name, const ItemTypeamp; itemType)
{
Item *newItem = Item::getInstance(name, itemType);
m_itemList.push_back(newItem);
}
void Cart::printItems()
{
std::cout << "Items" << std::endl;
for (int i = 0; i < m_itemList.size(); i )
{
m_itemList[i]->print();
}
std::cout << std::endl;
}
Когда я запускаю этот код, результат
Item name: Shirt
Item name: Shirt
Item name: Shirt
что мне нужно, так это
Item name: Shirt
Item name: Xbox
Item name: Bowl
Я изучаю шаблон проектирования. Я знаю, что цель этого — создать только один экземпляр. В этом примере я должен использовать одноэлементный шаблон. Но я не знаю, где я ошибаюсь, поэтому я получаю этот результат. Не могли бы вы сказать мне, где я должен исправить свой код? Большое спасибо!
Комментарии:
1. Ни один класс, который вы показали здесь, не кажется хорошим кандидатом для singleton, и особенно нет
Item
.2. Разве несколько экземпляров и одноэлемент не противоречат друг другу? Вы имеете в виду что-то вроде уникального экземпляра в наборе или карте?
3. Что касается шаблонов проектирования , я полагаю, вам нужна фабрика , которая, в свою очередь, может быть реализована как одноэлементный или фабричный метод . На самом деле конкретная проблема заключается в том
static Item* m_instance;
, чтоItem
одновременно допускается только один экземпляр, когда вам нужно их много.4. @gnase вы добавляете несколько «элементов» в корзину, поэтому просто не имеет смысла, чтобы в памяти был только 1
Item
объект, вам нужно несколькоItem
объектов. Поэтому использование одноэлементного дизайна дляItem
не имеет смысла.Item *newItem = Item::getInstance(name, itemType);
должно бытьItem *newItem = new Item(name, itemType);
вместо этого, если вы не избавитесь отItem::m_instance
него полностью и не изменитеItem::getInstance()
его на returnnew Item(name, itemType)
каждый раз, когда он вызывается.5. @gnase Абстрактный класс с
private
конструктором был бы немного бесполезным, не так ли? Но хорошо,getInstance()
если вы все еще можете раздавать указатели, созданные сnew
помощью, просто не храните их вstatic Item* m_instance;
.