C++调用vector内对象方法报错C2259无法实例化抽象类如何解决
报错原因
- 核心原因1:你继承的
sf::Drawable类包含纯虚函数virtual void draw(sf::RenderTarget&, sf::RenderStates) const = 0,你当前的Object类没有实现该纯虚函数,因此Object本身就是抽象类,C++不允许抽象类直接实例化。你声明std::vector<Object>时要求容器存储可实例化的Object对象,直接触发C2259报错。 - 核心原因2:你调用
startupVector.push_back(*this)时会触发Object类的拷贝构造,相当于尝试实例化抽象类,是报错的直接触发点。 - 额外问题:即便你补全了纯虚函数实现,直接用
std::vector<Object>存储基类值也会发生对象切片,丢失多态特性,后续调用onStartup等方法时永远只会执行基类实现,无法触发子类重写的逻辑。
解决步骤
- 补全
Object类从sf::Drawable继承的纯虚函数draw的实现,或者将该函数继续声明为纯虚,明确Object为抽象基类。 - 将三个vector的存储类型从
Object值类型改为基类智能指针,规避抽象类实例化问题的同时保留多态能力,因为你的场景需要在三个vector中存储同一个实例,推荐使用std::shared_ptr<Object>。 - 修改往vector中添加元素的逻辑,不再做对象值拷贝,改为存入指向当前实例的智能指针。
- 调整遍历逻辑,通过智能指针调用目标方法即可正常触发多态。
代码修改示例
头文件修改
#include <memory> // 引入智能指针头文件 #include <string> #include <vector> #include <SFML/Graphics.hpp> // 继承enable_shared_from_this用于安全获取当前实例的shared_ptr class Object : public sf::Transformable, public sf::Drawable, public std::enable_shared_from_this<Object> { public: Object(); virtual ~Object(); void init(std::string texturePath); virtual void onStartup(); virtual void onUpdate(); // 逐帧调用 virtual void onShutdown(); protected: // 补全sf::Drawable要求的纯虚函数实现 void draw(sf::RenderTarget& target, sf::RenderStates states) const override { states.transform *= getTransform(); // 替换为你自己的绘制逻辑,这里以绘制内部精灵为例 target.draw(m_sprite, states); } private: sf::Sprite m_sprite; sf::Texture m_texture; }; // vector存储类型改为智能指针 static std::vector<std::shared_ptr<Object>> startupVector; static std::vector<std::shared_ptr<Object>> updateVector; static std::vector<std::shared_ptr<Object>> shutdownVector; void startupVectorHandler(); void updateVectorHandler(); void shutdownVectorHandler();
逻辑代码修改
void Object::init(std::string texturePath) { // 原有纹理加载逻辑保留 m_texture.loadFromFile(texturePath); m_sprite.setTexture(m_texture); // 改为存入当前实例的智能指针,不再做值拷贝 startupVector.push_back(shared_from_this()); updateVector.push_back(shared_from_this()); shutdownVector.push_back(shared_from_this()); } void startupVectorHandler() { for (auto& objPtr : startupVector) { objPtr->onStartup(); } // 启动逻辑执行完后可清空vector,避免重复调用 startupVector.clear(); }
内容的提问来源于stack exchange,提问作者Karol739
相关产品推荐
相关产品推荐

