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

向上转型后抽象父类指针无法获取子类属性及正确调用方法

问题原因与解决:父类指针无法获取子类成员变量值

问题核心

你遇到的问题是成员变量没有多态特性:子类slack中重新声明的type并不是对父类operation中type的重写,而是直接隐藏了父类的同名成员。当通过父类指针operation* op访问type时,编译器只会解析到父类中定义的type(值为-1),不会像虚函数那样动态绑定到子类的成员。而虚函数能正常工作,是因为它们依赖C++的虚函数表(vtable)实现了动态多态。

解决方案

方案1:复用父类的type成员(推荐)

取消子类中对type的重新声明,改为在子类构造函数中初始化从父类继承来的type:

修改父类,确保type可以被子类初始化:

class operation {
public:
    ll time, bot;
    ll type;
    // 父类构造函数初始化默认值
    operation() : type(-1) {}
    virtual void negate() = 0;
    virtual void print() = 0;
    virtual void execute() = 0;
};

修改子类,在构造函数中赋值父类的type:

class slack:public operation{
public:
    slack() {
        type = op::slack; // 直接修改继承的父类成员
    }
    // 其余虚函数实现不变
    virtual void print() override {if(nExec == k) exit(0);cout << "Robot " << bot << " slacks off." << endl;}
    virtual void negate() override {}
    virtual void execute() override {
        if(nExec == k) exit(0);
        nExec++;
    }
};

方案2:添加虚函数获取type

如果希望通过多态方式获取type,可以在父类中定义一个虚函数来返回type,子类可按需重写:

class operation {
public:
    ll time, bot;
    ll type = -1;
    virtual void negate() = 0;
    virtual void print() = 0;
    virtual void execute() = 0;
    // 虚函数返回type
    virtual ll getType() const { return type; }
};

class slack:public operation{
public:
    ll type = op::slack;
    // 重写getType返回子类的type
    virtual ll getType() const override { return type; }
    // 其余虚函数实现不变
};

此时通过op->getType()就能获取子类的type值。

方案3:强制向下转型(不推荐)

如果必须保留子类的type成员,可以将父类指针强制转换为子类指针后访问,但这种方式破坏了多态的封装性,仅在确定指针指向子类对象时使用:

cout << static_cast<slack*>(op)->type << endl;

修改后的完整代码(方案1)

#include <iostream>
#include <vector>
#include <deque>
using std::string, std::cin, std::cout, std::vector, std::deque, std::endl;

typedef long long ll;
ll n, m, k, nExec;
namespace op {
    const ll slack = 0, move = 1, swap = 2, mirror = 3, replace = 4, activate = 5, trigger = 6;
}

class operation {
public:
    ll time, bot;
    ll type;
    operation() : type(-1) {}
    virtual void negate() = 0;
    virtual void print() = 0;
    virtual void execute() = 0;
};

class slack:public operation{
public:
    slack() {
        type = op::slack;
    }
    virtual void print() override {
        if(nExec == k) exit(0);
        cout << "Robot " << bot << " slacks off." << endl;
    }
    virtual void negate() override {}
    virtual void execute() override {
        if(nExec == k) exit(0);
        nExec++;
    }
};

int main() {
    k = 998244353;
    operation* op = new slack;
    cout << op->type << endl; // 输出0
    op->print();
    return 0;
}

运行后输出:

0
Robot 0 slacks off.

内容的提问来源于stack exchange,提问作者openwld

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:36:09