Hướng dẫn c++ pass class name as argument - c ++ chuyển tên lớp làm đối số

0

Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.
Learn more.

Tôi có một lớp trừu tượng. Đó là một nhà máy.

Vì vậy, các nhà máy khác có thể được kế thừa từ lớp này.

Tôi muốn chuyển lớp đó như một đối số cho một hàm.

Làm thế nào để làm điều đó ?

void Gui::registerControlFactory(std::string type, ControlFactory controlFactory)
{
    registeredControls[type] = controlFactory;
} 

Đây là lớp trừu tượng

static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};

Và đây là lớp tôi muốn đăng ký thông qua chức năng đăng ký của mình ở trên

static class MyControlsFactory : public ControlFactory
{
    Control* createControl(json j)
    {
        ...
    }
};

Tôi muốn có thể có thể:

gui->registerControlFactory("sometype", MyControlsFactory );

Tôi gặp lỗi:

Tên loại không được phép

Làm thế nào tôi có thể làm điều này trong C ++?

Cảm ơn bạn đã giúp đỡ

Hướng dẫn c++ pass class name as argument - c ++ chuyển tên lớp làm đối số

Amal k

3,8892 Huy hiệu vàng17 Huy hiệu bạc39 Huy hiệu đồng2 gold badges17 silver badges39 bronze badges

hỏi ngày 23 tháng 6 năm 2021 lúc 15:59Jun 23, 2021 at 15:59

10

Để có được hành vi mà bạn có thể đang tìm kiếm, bạn sẽ muốn trao đổi mọi thứ theo con trỏ:

// the interface will look like:
void Gui::registerControlFactory(std::string type, std::unqiue_ptr controlFactory)

// and then when registering:
gui->registerControlFactory("sometype", std::make_unique());

Nếu bạn muốn tránh tạo hoàn toàn lớp (âm thanh giống như mục tiêu của bạn), bạn có thể chuyển sang

static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};
0 thay vì
static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};
1s:

using Factory = std::function;
void Gui::registerControlFactory(std::string type, Factory controlFactory) {
    // assuming this is a std::map
    registeredControls[type] = std::move(controlFactory);
}

// then you could use it like:
gui->registerControlFactory("sometype", [](){ return build_control_thing(); });

Ngoài ra, tôi không nghĩ C ++ có khái niệm

static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};
2 để từ khóa có thể bị bỏ qua (giả sử nó biên dịch ở nơi đầu tiên).

Đã trả lời ngày 23 tháng 6 năm 2021 lúc 16:11Jun 23, 2021 at 16:11

Mattlangfordmattlangfordmattlangford

1.2611 huy hiệu vàng7 Huy hiệu bạc12 Huy hiệu đồng1 gold badge7 silver badges12 bronze badges

Bạn thường truyền các đối tượng, hoặc tài liệu tham khảo và con trỏ cho các đối tượng, xung quanh; C ++ có thể xử lý tên loại như tham số chỉ trong các mẫu.

Tuyên bố

static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};
3 có vẻ kỳ lạ, cho rằng ControlFactory là một loại trừu tượng không thể được khởi tạo. .

Những gì tôi mong đợi ở đây như một mẫu chung là một tham chiếu hoặc một con trỏ đến lớp cơ sở cho phép bạn chuyển một tham chiếu hoặc con trỏ đến một lớp dẫn xuất thực hiện giao diện này. Việc triển khai đó sẽ có một hàm tạo và không còn chức năng ảo thuần túy nữa, vì vậy người ta có thể dễ dàng tạo các đối tượng thuộc loại nhà máy có nguồn gốc đó.

Nếu tuyên bố là

static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};
4, bạn chỉ đơn giản là nói điều gì đó như

gui->registerControlFactory("sometype", new MyControlsFactory);

Điều này giả định rằng GUI có quyền sở hữu nhà máy và xử lý nó khi thực hiện, hoặc cuộc sống của GUI là của chương trình dù sao đi nữa để không cần phải xử lý. Nếu đó không phải là trường hợp bạn cần ghi nhớ địa chỉ của nhà máy điều khiển mới ở đâu đó trước khi chuyển nó cho GUI.

Đã trả lời ngày 23 tháng 6 năm 2021 lúc 16:22Jun 23, 2021 at 16:22

Hướng dẫn c++ pass class name as argument - c ++ chuyển tên lớp làm đối số

Có vẻ như bạn muốn lưu trữ các loại trong bản đồ và khởi tạo một đối tượng dựa trên khóa và loại nào được lưu trữ trong bản đồ. C ++ không thể làm điều này theo cách bạn nghĩ, vì vậy bạn sẽ phải làm việc xung quanh nó.

Một tùy chọn sẽ là lưu trữ lambdas trong bản đồ. Cái gì đó như:

using ControlBuilder = std::function;
using FactoryMap = std::map;

FactoryMap registeredControls;

void Gui::registerControlFactory(std::string type, ControlBuilder buildFunc)
{
    registeredControls[type] = buildFunc;
}

Vì vậy, bây giờ bạn có thể làm một cái gì đó như:

gui->registerControlFactory("sometype", [](const json& j)
    { 
         MyControlsFactory factory; 
         return factory.createControl(j);
    });

Điều này sẽ không khởi tạo đối tượng

static class ControlFactory
{
public:
    virtual Control* createControl(json j)=0;
};
5 cho đến khi bạn đã sẵn sàng gọi nó, điều mà bạn có thể làm như vậy:

auto control = registeredControls["sometype"](somejsonobject);

Đã trả lời ngày 23 tháng 6 năm 2021 lúc 16:35Jun 23, 2021 at 16:35

Hướng dẫn c++ pass class name as argument - c ++ chuyển tên lớp làm đối số

AddyaddyAddy

2.3561 Huy hiệu vàng22 Huy hiệu bạc42 Huy hiệu đồng1 gold badge22 silver badges42 bronze badges

1

Làm thế nào để bạn vượt qua một lớp như một đối số trong C ++?

Để truyền một đối tượng làm đối số, chúng tôi viết tên đối tượng làm đối số trong khi gọi hàm giống như cách chúng tôi thực hiện cho các biến khác. Cú pháp: function_name (object_name); Ví dụ: Trong ví dụ này, có một lớp có biến số nguyên 'A' và hàm 'thêm' lấy một đối tượng làm đối số.write the object name as the argument while calling the function the same way we do it for other variables. Syntax: function_name(object_name); Example: In this Example there is a class which has an integer variable 'a' and a function 'add' which takes an object as argument.

Chúng ta có thể vượt qua lớp như một đối số cho phương pháp không?

Chúng ta có thể truyền dữ liệu đến các phương thức dưới dạng đối số và một đối tượng là một thể hiện của một lớp được tạo động.Các loại dữ liệu cơ bản có thể được truyền dưới dạng đối số cho các phương thức C# giống như cách đối tượng cũng có thể được truyền dưới dạng đối số cho một phương thức. and an object is an instance of a class that is created dynamically. The basic data types can be passed as arguments to the C# methods in the same way the object can also be passed as an argument to a method.

Bạn có thể vượt qua một lớp học như một cuộc tranh luận trong Python không?

Có của thô, bạn có thể vượt qua các lớp hoặc chức năng hoặc thậm chí các mô -đun ... ...

Làm cách nào để lấy tên lớp của một đối tượng trong Python?

Phương pháp đầu tiên và dễ dàng nhất để có được một tên lớp trong Python là bằng cách sử dụng thuộc tính __ class__ mà về cơ bản đề cập đến lớp của đối tượng chúng ta muốn truy xuất.Ở đây chúng tôi kết hợp thuộc tính với thuộc tính __name__ để xác định tên lớp của đối tượng hoặc thể hiện.using __class__ property which basically refers to the class of the object we wish to retrieve. Here we combine the property with __name__ property to identify the class name of the object or instance.