多态对象和unique_ptr的向量

Vector of polymorphic objects and unique_ptr

提问人:Different 提问时间:9/8/2023 最后编辑:Jan SchultkeDifferent 更新时间:9/8/2023 访问量:86

问:

我正在尝试做一项作业,这次决定正确管理记忆,但最终问题多于答案。例如,我想要一个父类的子类向量,据我所知,我需要使用指针来避免切片我的对象,所以,vector<Parent> listvector<Parent*>

然后,我了解了 c++ 中的智能指针,还了解了如果调用父类的析构函数(可能是智能指针超出范围等等)时发生的潜在内存泄漏。我不知道编写我的类以避免内存泄漏的正确方法是什么,我写了一个我所处的例子,这是打印“This is A”,我认为这意味着如果析构函数被指针调用,它会导致内存泄漏。

public:
    virtual void funct(){
        cout << "This is A" << endl;
    }
};
class B : public A{
public:
    void funct(){
        cout << "This is B" << endl;
    }
};

int main() {
    B b;

    auto ptr = make_unique<A>(b);

    ptr.get()->funct();

    return 0;
}

从注释中获取内容,这是否足以不导致内存泄漏,这意味着如果我删除唯一的指针 ptr,它会释放分配给 B 的内存吗?

class A{
public:
    virtual void funct(){
        cout << "This is A" << endl;
    };
    virtual ~A() = default;
};
class B : public A{
public:
    void funct() override{
        cout << "This is B" << endl;
    }
    
    ~B() override = default;
};

int main() {
    B b;

    unique_ptr<A> ptr = make_unique<B>(b);

    ptr->funct();

    return 0;
}
C++ 多态性 unique-ptr 虚拟析构函数

评论

1赞 Some programmer dude 9/8/2023
无关:更改为ptr.get()->funct()ptr->funct()
1赞 Some programmer dude 9/8/2023
您的问题是对象切片。您创建了一个对象,但您需要一个实际对象。使用指向基类的指针,但使用指向子类的指针初始化它:,后跟 .这将调用 ,即使它指向一个指针(因为它确实指向一个对象)。ABstd::unique_ptr<A> ptr = std::make_unique<B>();ptr->funct()B::functptrAB
1赞 Some programmer dude 9/8/2023
关于您对泄漏的担忧,没有泄漏。问题只与你有一个对象有关,而不是一个对象。AB
1赞 wohlstad 9/8/2023
旁注:基类应该有一个虚拟析构函数来支持多态破坏。
1赞 molbdnilo 9/8/2023
make_unique<A>(b)几乎等同于 。你现在能发现问题吗?unique_ptr<A>(new A(b))

答:

2赞 deviantgeek 9/8/2023 #1

为了确保从智能指针(实际上任何分配的对象)中正确释放内存,您只需要确保基类析构函数标记为虚拟。

class A
{
public:
    A() {}
    virtual ~A() = default;
    virtual void func() {};
};

class B : public A
{
public:
    B() {}
};

class C : public B
{
public:
    C() {}
    void func() override {}
};

auto obj = std::make_unique<C>();

当超出范围时,它将正确释放内存。您甚至不需要在其他类中指定析构函数,因为它们已经获得了默认的析构函数。但是,基需要标记为虚拟,因此这就是为什么您需要在基类中指定析构函数的原因。obj