有没有一种方法可以复制派生 class 指针的向量而不将其强制转换为基础 class?
Is there a way to copy a vector of derived class pointers without casting it to the base class?
我有 4 个 class:1 个 Base
、2 个 Derived
和 1 个 Container
class。
Container
class 包含 Base
个指针的向量。
我想为我的 class Container
创建一个复制构造函数,它不会将 Derived
指针转换为 Base
,这样我就可以将Base
指向 Derived
之后的指针。
class Base {
int m_base_attribute;
public:
Base() : m_base_attribute(420) {}
virtual void say_hello() {
std::cout << "Hello !" << std::endl;
}
};
class Derived : public Base {
int m_derived_attribute;
public:
Derived() : Base(), m_derived_attribute(69) {}
virtual void say_hello() {
std::cout << "I'm a derived class !" << std::endl;
}
};
class Container {
std::vector<Base*> m_base_vector;
public:
Container() {
m_base_vector.push_back(new Derived());
}
Container(const Container& model) {
for(auto base : model.m_base_vector){
m_base_vector.push_back(new Base(*base));
}
}
~Container() {
for(auto base : m_base_vector) {
delete base;
}
}
};
有没有办法做到没有任何内存泄漏?
问题是 new Base(*base)
总是创建一个 Base
对象,而不是 Derived
对象。这叫做slicing。解决方法是使用虚拟 clone
函数和虚拟析构函数:
class Base {
int m_base_attribute;
public:
// ...
virtual std::unique_ptr<Base> clone() const
{
return std::make_unique<Base>(*this);
}
virtual ~Base() {}
};
class Derived : public Base {
int m_derived_attribute;
public:
// ...
std::unique_ptr<Base> clone() const override
{
return std::make_unique<Derived>(*this);
}
};
请注意,我使用 std::unique_ptr
而不是原始指针来避免内存泄漏。现在你可以在没有切片的情况下实现 Container
class:
class Container {
std::vector<std::unique_ptr<Base>> m_base_vector;
public:
// ...
Container(const Container& model)
{
m_base_vector.reserve(model.m_base_vector.size());
for (const auto& p : m_base_vector) {
m_base_vector.push_back(p->clone());
}
}
};
我有 4 个 class:1 个 Base
、2 个 Derived
和 1 个 Container
class。
Container
class 包含 Base
个指针的向量。
我想为我的 class Container
创建一个复制构造函数,它不会将 Derived
指针转换为 Base
,这样我就可以将Base
指向 Derived
之后的指针。
class Base {
int m_base_attribute;
public:
Base() : m_base_attribute(420) {}
virtual void say_hello() {
std::cout << "Hello !" << std::endl;
}
};
class Derived : public Base {
int m_derived_attribute;
public:
Derived() : Base(), m_derived_attribute(69) {}
virtual void say_hello() {
std::cout << "I'm a derived class !" << std::endl;
}
};
class Container {
std::vector<Base*> m_base_vector;
public:
Container() {
m_base_vector.push_back(new Derived());
}
Container(const Container& model) {
for(auto base : model.m_base_vector){
m_base_vector.push_back(new Base(*base));
}
}
~Container() {
for(auto base : m_base_vector) {
delete base;
}
}
};
有没有办法做到没有任何内存泄漏?
问题是 new Base(*base)
总是创建一个 Base
对象,而不是 Derived
对象。这叫做slicing。解决方法是使用虚拟 clone
函数和虚拟析构函数:
class Base {
int m_base_attribute;
public:
// ...
virtual std::unique_ptr<Base> clone() const
{
return std::make_unique<Base>(*this);
}
virtual ~Base() {}
};
class Derived : public Base {
int m_derived_attribute;
public:
// ...
std::unique_ptr<Base> clone() const override
{
return std::make_unique<Derived>(*this);
}
};
请注意,我使用 std::unique_ptr
而不是原始指针来避免内存泄漏。现在你可以在没有切片的情况下实现 Container
class:
class Container {
std::vector<std::unique_ptr<Base>> m_base_vector;
public:
// ...
Container(const Container& model)
{
m_base_vector.reserve(model.m_base_vector.size());
for (const auto& p : m_base_vector) {
m_base_vector.push_back(p->clone());
}
}
};