我有一个c ++程序,其中我:
void (*foo)
和void (*bar)
namespace1
包含函数void foo()
和void bar()
namespace2
还包含函数void foo()
和void bar()
在运行时,我希望用户能够传递一个变量,比如choice
,它表示所选的命名空间。然后,类中的函数将映射到相应名称空间中的相应函数。
目前,我正在使用以下内容:
if (choice == "namespace1") {
my_class.foo = &(namespace1::foo);
my_class.bar = &(namespace1::bar);
} else if (choice == "namespace2") {
my_class.foo = &(namespace2::foo);
my_class.bar = &(namespace2::bar);
}
这很好用,但是当我的可用命名空间列表增加并且每个命名空间提供了9个我希望传递给类的函数时,它变得相当麻烦。
有什么方法可以整理一下吗?我的第一个想法是:
if (choice == "namespace1") {
my_namespace = namespace1;
} else if (choice == "namespace2") {
my_namespace = namespace2;
}
my_class.foo = &(my_namespace::foo);
my_class.bar = &(my_namespace::bar);
但是,如果我理解正确,我就不能使用名称空间作为变量。
有没有更好的方法来制定这个?结构化,这种风格很差,有没有更标准的方法来解决这个问题?
感谢您提供任何见解!
答案 0 :(得分:6)
您应该了解编译的各个阶段,至少近似。名称在运行时根本不存在。您现有的代码通过为每个名称空间中的每个名称创建指针来工作。
标准解决方案是定义接口。
class IFooBar {
virtual void foo() = 0;
virtual void bar() = 0;
// Other 7 functions.
};
这允许每个命名空间定义一个类而不是9个函数。
有可能幕后的编译器会创建一个“vtable”,一个函数指针数组,来实现这个接口。这与您现在大致相同,但随后自动化,没有复制粘贴错误的可能性。
答案 1 :(得分:1)
我建议使用特征。
Use case
然后像这样使用:
<app-upload-file
[uploadFileConfig]="...."
(filesAdded)="....">
</app-upload-file>
**********
formCvData: FormData = new FormData();
onFileUploaded($event) {
const uploaded = $event;
this.formLmData.set('.....', uploaded, uploaded.name);
}
你的问题是在运行时评估这些东西。
答案 2 :(得分:0)
展开the answer by @MSalters ...
有一种设计模式可以解决这种情况。它被称为Dependency Injection Pattern。
您的课程(您尝试存储foo
和bar
的地方)是客户。
名称空间包含实现接口的类。
依赖注入器需要将依赖项(指向名称空间中某个具体类的指针)注入客户端。