我有一个对象,根据构建配置在编译期间实例化.就所考虑的周围软件而言,该对象公开了相同的接口.我想模拟一个事实,即在编译期间(即static polymorphism)进行实例化决策,而不是通常的动态多态性.
有没有办法描述静态多态UML class diagram?
这或多或少是我需要的:

显然,在编译时只会实例化上述类型定义中的一个.
C++是否有适当的接口实现,不使用vtable?
例如
class BaseInterface{
public:
virtual void func() const = 0;
}
class BaseInterfaceImpl:public BaseInterface{
public:
void func(){ std::cout<<"called."<<endl; }
}
BaseInterface* obj = new BaseInterfaceImpl();
obj->func();
Run Code Online (Sandbox Code Playgroud)
在最后一行调用func到vtable来查找BaseInterfaceImpl :: func的func ptr,但是有没有C++方法直接这样做,因为除了纯接口类BaseInterface之外,BaseInterfaceImpl不是从任何其他类继承的?
谢谢.吉尔.
这种模式的目的是什么?这叫什么?当我第一次看到它时,它看起来很奇怪,尽管我现在已经看过很多次了.
template<typename Derived>
struct Base {
//...
};
struct Example : Base<Example> {
//...
};
Run Code Online (Sandbox Code Playgroud) 我有一个设计模式,其中有一个对象生成器(MorselGenerator及其子代),其中任何实例总是生成相同的确切类型的对象(Morsels及其子代),但类型检查器将不允许我执行任何操作两个或更多这些生成的对象,相信它们可能不同.
如何通过类型检查器?
trait Morsel
{
type M <: Morsel
def calories : Float
def + (v : M) : M
}
trait MorselGenerator
{
type Mg <: Morsel
def generateMorsel : Mg
}
class HotDog(c : Float, l : Float, w : Float) extends Morsel
{
type M = HotDog
val calories : Float = c
val length : Float = l
val width : Float = w
def + (v : HotDog) : HotDog = new HotDog(v.calories + calories, …Run Code Online (Sandbox Code Playgroud) scala type-inference abstract-type static-polymorphism dependent-type
我想知道如何在不使用虚函数的情况下在 C++ 中声明一个接口。经过一些互联网搜索,我整理了这个解决方案:
#include <type_traits>
using namespace std;
// Definition of a type trait to check if a class defines a member function "bool foo(bool)"
template<typename T, typename = void>
struct has_foo : false_type { };
template<typename T>
struct has_foo<T, typename enable_if<is_same<bool, decltype(std::declval<T>().foo(bool()))>::value, void>::type> : true_type { };
// Definition of a type trait to check if a class defines a member function "void bar()"
template<typename T, typename = void>
struct has_bar : false_type { };
template<typename T>
struct has_bar<T, …Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个通用算法.到目前为止,我已经使用类层次结构和指针实现了这一点,如下例所示:
struct Base{
virtual double fn(double x){return 0;}
};
class Derived : public Base{
double A;
public:
Derived(double a) : A(a) {}
double fn(double x) { return A*x;}
};
//Some other implementations
class algo{
double T;
std::unique_ptr<Base> b_ptr;
public:
algo(double t, std::unique_ptr<Base>& _ptr); //move constructor...
//Some constructors
double method(double x){ return T*b_ptr->fn(x);}
};
Run Code Online (Sandbox Code Playgroud)
然后按如下方式实现此设置:
int main(){
std::unique_ptr<Derived> ptr(new Derived(5.4));
algo(3.2,ptr);
method(2.4);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当然,这是一个非常简单的例子,但它适用于我的问题.据我所知,以这种方式使用派生类意味着该方法是在运行时而不是在编译时选择的.因为我的算法不需要任何动态行为 - 所有内容都是在编译时确定的 - 这是一种不必要的效率损失.有没有办法在编译时执行上述操作,即静态多态?
据我所知,只有使用模板才能获得静态多态性.但是,我无法找到具有非基本类型的工具模板.如上例所示,我需要使用非默认构造函数的派生类,这似乎不可能......任何人都可以提供任何解决方案来解决这个问题吗?
标题几乎说明了一切:在C ++中,有没有一种方法可以在编译时获取类的基本类型?即 是否可以将一个类传递给模板,并让该模板使用将给定类的基础传递给它的其他模板?
我的问题不是我自己是否可以实现这种功能,没有问题(使用特质等)。我的问题是,是否有一些(模糊的)内置功能可用于此目的。
我的程序的目的是创建一个数据列表,我可以在类层次结构中使用静态多态性时通过一组静态访问者访问该数据列表。
我通过 CRTP 利用静态多态性创建了一个类层次结构:
class VirtualBaseData {
public:
//someVirtualFunction
}
template<typename Derived>
class BaseData<Derived> {
public:
template<typename Visitor>
void accept(Visitor &v){
static_cast<Derived*>(this)->accept(v);
}
}
class DerivedBaseData1: BaseData<DerivedBaseData> {
public:
template<typename Visitor>
void accept(Visitor &v){
//Specific implementation
}
}
class DerivedBaseData2: BaseData<DerivedBaseData> {
public:
template<typename Visitor>
void accept(Visitor &v){
//Specific implementation
}
}
Run Code Online (Sandbox Code Playgroud)
我想将 DerivedBaseData 存储在一个容器中,以便稍后进行迭代和访问。
int main(){
std::vector<VirtualBaseData*> dataSet;
dataSet.push_back(new DerivedBaseData1);
dataSet.push_back(new DerivedBaseData2);
for(auto it = fifth.begin(); it != fifth.end(); ++it){
it->accept(); //Error: VirtualBaseData does not have a member function …Run Code Online (Sandbox Code Playgroud) c++ crtp static-polymorphism template-function static-visitor
Java 11(可能无关紧要):
public static String toString(Object obj) {
return ReflectionToStringBuilder.toString(obj, ToStringStyle.SHORT_PREFIX_STYLE);
}
public static String toString(Collection<Object> collection) {
return collection.stream()
.map(SaLogUtils::toString)
.collect(Collectors.joining(", ", "[", "]"));
}
public static void main(String[] args) {
List<Integer> list = List.of(Integer.valueOf(1));
System.out.println(SaLogUtils.toString(list));
System.out.println(SaLogUtils.toString(List.of(Integer.valueOf(1))));
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的输出:
// from toString(Object)
ImmutableCollections.List12[e0=1,e1=<null>]
// from toString(Collection<Object>)
[Integer[value=1]]
Run Code Online (Sandbox Code Playgroud)
为什么Java静态选择不同的方法?
java generics overload-resolution static-polymorphism java-11
C++ 核心指南建议dynamic_cast在“类层次结构导航不可避免”时使用。这触发铛,整洁抛出以下错误:Do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]。
指导方针继续说:
注意:
像其他演员一样,
dynamic_cast被过度使用。更喜欢virtual函数而不是铸造。在可能的情况下(不需要运行时解析)并且相当方便,更喜欢静态多态性而不是层次结构导航。
我一直只使用嵌套在我的基类中的enum命名Kind,并static_cast根据其类型执行 a 。阅读 C++ 核心指南,“...即便如此,根据我们的经验,诸如“我知道我在做什么”的情况仍然是一个已知的错误来源。” 建议我不应该这样做。通常,我没有任何virtual函数,所以 RTTI 不存在使用dynamic_cast(例如,我会得到error: 'Base_discr' is not polymorphic)。我总是可以添加一个virtual函数,但这听起来很傻。该指南还说在考虑使用我使用的判别方法之前先进行基准测试Kind。
enum class Kind : unsigned char {
A,
B,
};
class Base_virt {
public:
Base_virt(Kind p_kind) noexcept : m_kind{p_kind}, m_x{} …Run Code Online (Sandbox Code Playgroud) c++ polymorphism dynamic-cast static-polymorphism cpp-core-guidelines
c++ ×7
templates ×3
crtp ×2
interface ×2
polymorphism ×2
dynamic-cast ×1
generics ×1
java ×1
java-11 ×1
scala ×1
terminology ×1
uml ×1
vtable ×1