在c ++中声明在运行时对命名空间的引用

时间:2018-05-14 15:22:27

标签: c++ namespaces

我有一个c ++程序,其中我:

  1. 有一个类,其中包含作为成员的函数句柄,说void (*foo)void (*bar)
  2. 拥有一组名称空间,每个名称空间定义相同名称的函数,例如:
    • namespace1包含函数void foo()void bar()
    • namespace2还包含函数void foo()void bar()
  3. 在运行时,我希望用户能够传递一个变量,比如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);
    

    但是,如果我理解正确,我就不能使用名称空间作为变量。

    有没有更好的方法来制定这个?结构化,这种风格很差,有没有更标准的方法来解决这个问题?

    感谢您提供任何见解!

3 个答案:

答案 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

您的课程(您尝试存储foobar的地方)是客户。

名称空间包含实现接口的类。

依赖注入器需要将依赖项(指向名称空间中某个具体类的指针)注入客户端。