在方法中返回向上转换的指针时替代堆分配

Posted

技术标签:

【中文标题】在方法中返回向上转换的指针时替代堆分配【英文标题】:Alternative to heapallocation when returning a uppcasted pointer in a method 【发布时间】:2021-10-02 04:42:27 【问题描述】:

我的问题是我不允许使用任何堆分配。而且我有一个函数需要返回一个指向抽象类的指针。

例子:

class Base

public:
    virtual Base* func() = 0;
;

class Foo : public Base

    Base* func() override
    
        // return new Foo; // usual approach with heap allocation

        // Foo result; // undefined behaviour.
        // return &result;
    
;

这个例子可能有点过于简单,但它说明了问题。如何在没有堆分配的情况下实现 Foo::func?

【问题讨论】:

func 是否需要返回指向调用它的同一对象的指针?然后简单地return this; 如果它应该返回一个指向其他对象的指针,那么该对象的存储应该从哪里来,如果不是堆?预计如何管理这个新对象的生命周期?弄清楚设计,然后实施。 【参考方案1】:

也许这对您来说是一个选择:您可以将要创建新 Foo 对象的内存地址传递给函数,然后使用放置 new 创建对象。

那么,这块内存可以在堆栈上,避免堆分配。当然你也可以传递以前堆分配的内存,这仍然可以避免在Foo::func中创建时分配。

见下文:

class Base

public:
    virtual Base* func(std::byte*) = 0;
    virtual ~Base() = default;
;

class Foo : public Base

public:
    Base* func(std::byte* pMem) override
    
        return new (pMem) Foo;
    
;

int main() 

    // Buffer on stack
    std::byte buf[sizeof(Foo)];

    Foo f;
    auto pNew = f.func(buf);

    // Manually call destructor before buffer goes out of scope
    pNew->~Base();
    
    return 0;

【讨论】:

我实际上已经采用了类似的方法,但是示例方法过度简化了问题,因为我希望它是通用的并且类型安全,因为它用于用户将与之交互的库中.我将为我的方法提出一个新问题,因为我发现它具有未定义的行为。

以上是关于在方法中返回向上转换的指针时替代堆分配的主要内容,如果未能解决你的问题,请参考以下文章

指针做参数的动态内存分配与二重指针(上)

C语言中返回字符串函数的四种实现方法

alloca() 可以替代 C++ 中的自动指针吗?

d 对象的动态建立和释放

智能指针

分配函数和返回的指针