我正在尝试使用界面
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 :: Some Operation返回乘积a * b
用法如下
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;
}
由于可能的内存泄漏,我正在尝试避免新建/删除。 可以静态分配接口吗?
IDemo test = Child_A();
编译器不喜欢这样。
答案 0 :(得分:3)
这很简单。多态(接口)与动态分配无关。如果您不想动态分配,那就不要。
您的示例可以像这样轻松地工作:
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;
}
您可能需要一个更好的示例,该示例实际使用接口。
// 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;
}
答案 1 :(得分:1)
您可以写:
.scalePow()
,然后像以前一样继续操作(尽管不要Child_B b{};
IDemo *pDemo = &b;
)。
如果您想在特定位置销毁delete pDemo
,请使用花括号引入声明性区域。
答案 2 :(得分:1)
IDemo不是接口,它是抽象基类。您对命名约定的选择建议您来自C#背景。您应该意识到C#/ Java接口和C ++抽象基类之间的重要区别。 C#/ Java类实现多个接口是很常见的,也可以对C ++抽象(或具体)类进行类似的操作。在这样做之前,您应该了解钻石继承问题。请参阅以下堆栈溢出问题。
Multiple Inheritance from two derived classes。
要回答您的原始问题,请不要在声明中包含编译器错误消息:
IDemo测试= Child_A();
但是您想要做的是声明一个抽象基类的具体实例,并为其派生一个派生类的实例。那不是有效的C ++,也没有任何意义。 如果您使用的是抽象基类,则尝试利用多态性。在C ++中,这意味着基类型指针或对派生类的引用。
您可以使用:
const IDemo&test = Child_A();
这将要求将IDemo上的任何方法都声明为const,但我不推荐这种方法,因为谈论对临时对象或短暂对象的引用可能会导致问题,例如如果您将测试分配给寿命比函数范围更长的引用(例如,通过返回),则程序将崩溃。