You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
}

关键说明

  1. 为什么这样能解决问题?:每次调用new Dog()都会在堆上开辟一块全新的内存空间,生成一个独立的Dog对象。此时指针animal每次指向的都是不同的内存地址,修改每个对象的mDescription只会影响当前指向的那个对象,完全不会干扰其他实例。
  2. 内存泄漏提醒:使用裸指针管理堆内存时,一定要记得在容器使用完毕后遍历删除每个指针,否则这些堆内存会一直占用直到程序结束。如果你的项目使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:58:44