C++ use interfaces without dynamic allocation
我正在尝试使用接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class IDemo { public: virtual ~IDemo() {} virtual uint32_t Some_Operation(uint32_t a, uint32_t b) = 0; }; class Child_A : public IDemo { public: virtual uint32_t Some_Operation(uint32_t a, uint32_t b); }; class Child_B : public IDemo { public: virtual uint32_t Some_Operation(uint32_t a, uint32_t b); }; |
child_a::some_operation返回a+b的和child_b::某些操作返回产品a*b
用法如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | bool Test_Inferface() { IDemo* pDemo = new Child_B(); uint32_t product = pDemo->Some_Operation(1, 2); delete pDemo; if (2 != product) { return false; } pDemo = new Child_A(); uint32_t sum = pDemo->Some_Operation(1,2); delete pDemo; if(3 != sum) { return false; } return true; } |
由于可能发生内存泄漏,我正在尝试避免新建/删除。是否可以静态分配接口?
1 | IDemo test = Child_A(); |
编译器不喜欢这样。
这很简单。多态性(接口)与动态分配无关。如果您不想动态分配,那么就不要。
您的示例很容易这样工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | bool Test_Inferface() { Child_B child_b; uint32_t product = child_b.Some_Operation(1, 2); if (2 != product) { return false; } Child_A chile_a; uint32_t sum = child_a.Some_Operation(1,2); if(3 != sum) { return false; } return true; } |
您可能需要一个实际使用接口的更好的示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // here we have an interface reference parameter that doesn't care if what is // passed to it is dynamically allocated or sitting on the stack. uint32_t better_example(IDemo& demo) { return demo.Some_Operation(1, 2); } bool Test_Inferface() { Child_B child_b; uint32_t product = better_example(child_b); if (2 != product) { return false; } Child_A chile_a; uint32_t sum = better_example(child_a); if(3 != sum) { return false; } return true; } |
IDEMO不是接口,它是抽象基类。您对命名约定的选择表明您来自C背景。你应该意识到C/J/Java接口和C++抽象基类之间的一个重要区别。C语言的Java类实现多个接口是常见的,也有可能做类似C++抽象(或具体)类的事情。在这样做之前,您应该了解钻石继承问题。请参阅下面的堆栈溢出问题。
来自两个派生类的多重继承。
要回答原始问题,请不要包含声明的编译器错误消息:
IDEMO测试=子项_a();
但您要做的是声明抽象基类的具体实例,并为其分配派生类的实例。这不是有效的C++,也没有任何意义。如果您使用的是抽象基类,那么您将尝试利用多态性。在C++中,这意味着基类指针或派生类的引用。
你可以使用:
const-idemo&test=child_a();
这将要求IDEMO上的任何方法都声明为const,而不是我建议的方法,因为谈论对临时或短期对象的引用可能会导致问题,例如,如果将测试分配给比函数作用域更长的引用(例如,通过返回该引用),则程序将崩溃。
你可以写:
1 2 | Child_B b{}; IDemo *pDemo = &b; |
然后像以前一样继续(但不要这样做)。
如果您想在某一点上销毁