Gần đây, tôi đã đăng câu hỏi về SO liên quan đến việc sử dụng một lớp học mang một chút chức năng riêng biệt mà lẽ ra nó nên có, lý tưởng. Tôi đã được khuyến khích để tìm hiểu về mô hình singleton để chỉ có một ví dụ được tạo ra của lớp và nó quản lý tập hợp các hoạt động xoay quanh dữ liệu mà nó đóng gói. Bạn có thể xem câu hỏi tại đây - using Static Container for base and derived classes.sử dụng không gian tên thay vì singletons
Bây giờ xem xét mã này -
#include <iostream>
#include <string>
#include <unordered_map>
class A{
std::string id;
public:
A(std::string _i): id(_i){}
virtual void doSomething(){std::cout << "DoSomethingBase\n";}
};
class B : public A{
std::string name;
public:
B(std::string _n):name(_n), A(_n){}
void doSomething(){std::cout << "DoSomethingDerived\n";}
};
namespace ListA{
namespace{
std::unordered_map<std::string, A*> list;
}
void init(){
list.clear();
}
void place(std::string _n, A* a){
list[_n] = a;
}
}
int main() {
ListA::init();
ListA::place("b1", new B("b1"));
ListA::place("a1", new A("a1"));
return 0;
}
Bỏ qua thực tế là tôi vẫn đang sử dụng con trỏ nguyên được rò rỉ bộ nhớ nếu chương trình không chấm dứt vì nó là, đây là một tốt thay thế cho việc sử dụng các biến tĩnh toàn cầu, hoặc một singleton?
Đối với câu hỏi trước, tôi đã sắp xếp lại lớp A (lớp cơ sở) và lớp B (lớp bắt nguồn) độc lập với không gian tên quản lý danh sách các đối tượng này. Vì vậy, đây là một ý tưởng tốt, hoặc một thực hành hoàn toàn xấu? Có bất kỳ thiếu sót nào cho nó?
Một thực hiện singleton tốt tôi đã được đề xuất như sau -
class EmployeeManager
{
public:
static EmployeeManager& getInstance()
{
static EmployeeManager instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
private:
EmployeeManager() {};
std::unordered_map<std::string, Employee&> list;
public:
EmployeeManager(EmployeeManager const&) = delete;
void operator=(const&) = delete;
void place(const std::string &id, Employee &emp){
list[id] = emp;
}
};
class Employee
{
public:
virtual void doSomething() = 0;
};
class Writer : public Employee
{
private:
std::string name_;
public:
Writer(std::string name) : name_(name) {};
void doSomething() { };
};
Thành thực mà nói tôi chưa bao giờ cố gắng Singleton pattern và tôi ngần ngại sử dụng nó trực tiếp kể từ khi tôi đã không có kinh nghiệm trước và tôi muốn sử dụng nó lần đầu tiên trong các dự án thú cưng của tôi.
Phản ứng của bạn đối với ai đó đề xuất mẫu đơn nên giống như khi bạn gặp một người đưa bạn đến phòng sau và sau một vài vòng xì phé gợi ý rằng "chúng ta nên làm cho nó thú vị". –
Mẫu đơn là một cách để * ép buộc * người dùng chỉ tạo một thể hiện. Bạn có cảm thấy một yêu cầu để tạo ra nhiều trường hợp khi bạn thực sự cần chỉ một? Nếu không, chỉ cần tạo đối tượng bạn cần và được thực hiện với nó! –
@BoPersson tôi có thực sự cần tạo đối tượng cho trường hợp sử dụng của mình không? Tôi không chỉ cần một std :: bản đồ với một số chức năng chuyên ngành liên quan đến nó? –