C++使用无动态分配的接口

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;

然后像以前一样继续(但不要这样做)。

如果您想在某一点上销毁b,那么可以使用大括号来引入声明性区域。