2017-08-09 36 views
0

我有一个Controller类,它被设计为继承。目前,它有一个name()纯虚方法,像这样:C++编译时和运行时可用的名称属性

class Controller { 
public: 
    virtual const std::string name() const = 0; 
} 

的名字确实是一个类的属性,而不是一个实例属性。它不应该在一个子类的实例之间改变,所以真的,虚拟不是在这里做的最好的事情。无论如何,我现在遇到了一个问题,我需要在编译时使用模板函数的名称。显然T::name()不起作用,并且因为子类不会默认可构造,所以我甚至无法用T()::name()来破解它。

所以有些事情需要改变,但我无法弄清楚这样做的最好方法。我需要能够在下列情况下访问名称:

  • 在编译时,当我有一个子类类型(例如T::name()
  • 在运行时,当我有一个子类的实例(例如, instance->name()
  • 在运行时,当我有一个Controller*(如指向基类)

name()不必是方法,它可以是公共属性,或别的东西。但无论我尝试什么,我似乎只能满足上述3个要求中的2个。

任何人都可以提出解决这个问题的好办法吗?

+2

你是什么意思“在编译时”?你需要在编译时使用字符串运行什么样的语句? –

+0

提示:[不可能](https://stackoverflow.com/questions/27123306/is-it-possible-to-use-stdstring-in-a-constexpr) –

+0

在模板函数中,我需要获取名称的传入类型。例如'template bool has_controller()const {...这里需要T :: name()...} – Kazade

回答

1

不幸的是,你不能声明虚拟静态方法,所以这样的事情是行不通的:

struct BaseClass { 
    static virtual std::string name() =0; 
}; 

struct ChildClass { 
    static std::string name() { 
    return "my_name"; 
    } 
}; 

可以改为制作法稍有不同的名称:

struct BaseClass { 
    virtual std::string name() =0; 
}; 

struct ChildClass { 
    std::string name() { 
    return ChildClass::_name(); 
    }; 

    static std::string _name() { 
    return "my_name"; 
    } 
}; 

这将与你描述的三种情况一起工作:

ChildClass c; 
BaseClass& b = c; 
std::cout << ChildClass::_name() << std::endl; 
std::cout << c.name() << std::endl; 
std::cout << b.name() << std::endl;