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

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等方法时永远只会执行基类实现,无法触发子类重写的逻辑。
解决步骤
  1. 补全Object类从sf::Drawable继承的纯虚函数draw的实现,或者将该函数继续声明为纯虚,明确Object为抽象基类。
  2. 将三个vector的存储类型从Object值类型改为基类智能指针,规避抽象类实例化问题的同时保留多态能力,因为你的场景需要在三个vector中存储同一个实例,推荐使用std::shared_ptr<Object>。
  3. 修改往vector中添加元素的逻辑,不再做对象值拷贝,改为存入指向当前实例的智能指针。
  4. 调整遍历逻辑,通过智能指针调用目标方法即可正常触发多态。
代码修改示例

头文件修改

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:54:04