C++多态场景下如何独立修改vector内指针指向的对象实例
问题:C++多态容器中如何让每个对象属性独立修改?
我在C++中用指针实现多态,把派生类指针存入std::vector<Animal*>容器。现在修改同一指针指向的对象属性时,所有该指针的副本指向的对象都会受影响(这确实是指针的特性),但我希望能独立修改每个对象的属性,请问这可行吗?
当前代码
主函数
#include "Cat.h" #include "Dog.h" #include <vector> int main() { std::vector<Animal*> animalVector; Animal* animal; animal = new Dog(); animal->setDescription("Good Dog"); animalVector.push_back(animal); animal->setDescription("Bad Dog"); animalVector.push_back(animal); animal = new Cat(); animal->setDescription("Good Cat"); animalVector.push_back(animal); for (auto& it : animalVector) { it->info(); } }
基类 Animal
#pragma once #include <string> using std::string; class Animal { protected: string mType; //! Holds the type of the Animal string mDescription; //! Holds the description of the Animal public: Animal(); virtual ~Animal(); virtual void info(); virtual void setDescription(string description) {mDescription = description;} };
派生类 Dog
#pragma once #include "Animal.h" class Dog : public Animal { public: Dog(); };
当前输出
Bad Dog Bad Dog Good Cat
期望输出
Good Dog Bad Dog Good Cat
回答
这当然可行!你现在的问题核心很简单:你只创建了一个Dog对象,两次往animalVector里添加的都是指向这个对象的指针副本。就像好几个人拿着同一扇门的钥匙,不管谁拧钥匙修改房间里的东西,所有人看到的都是同一个房间的变化。
要让每个容器元素对应独立的对象,你只需要为每个要存入容器的实例单独分配内存——也就是每次需要新对象时,都调用new创建一个全新的实例:
修改后的主函数代码
#include "Cat.h" #include "Dog.h" #include <vector> int main() { std::vector<Animal*> animalVector; // 创建第一个独立的Dog对象并配置属性 Animal* animal = new Dog(); animal->setDescription("Good Dog"); animalVector.push_back(animal); // 重新new一个全新的Dog对象,配置不同属性 animal = new Dog(); animal->setDescription("Bad Dog"); animalVector.push_back(animal); // 创建独立的Cat对象 animal = new Cat(); animal->setDescription("Good Cat"); animalVector.push_back(animal); // 输出每个对象的信息 for (auto& it : animalVector) { it->info(); } // 重要:手动释放堆内存,避免内存泄漏 for (auto& it : animalVector) { delete it; } animalVector.clear(); }
关键说明
- 为什么这样能解决问题?:每次调用
new Dog()都会在堆上开辟一块全新的内存空间,生成一个独立的Dog对象。此时指针animal每次指向的都是不同的内存地址,修改每个对象的mDescription只会影响当前指向的那个对象,完全不会干扰其他实例。 - 内存泄漏提醒:使用裸指针管理堆内存时,一定要记得在容器使用完毕后遍历删除每个指针,否则这些堆内存会一直占用直到程序结束。如果你的项目使用C++11或更高版本,更推荐使用
std::unique_ptr<Animal>来自动管理内存,这样就不用手动调用delete了:// 容器定义改为智能指针类型 std::vector<std::unique_ptr<Animal>> animalVector; // 存入对象时用make_unique创建 animalVector.push_back(std::make_unique<Dog>()); animalVector.back()->setDescription("Good Dog");
修改后的输出
Good Dog Bad Dog Good Cat
内容的提问来源于stack exchange,提问作者charis
相关产品推荐
相关产品推荐

