从派生类永久更改基类?

Posted

技术标签:

【中文标题】从派生类永久更改基类?【英文标题】:Change base class from derived class permanently? 【发布时间】:2020-06-08 17:49:03 【问题描述】:

所以,我的问题是我想从派生类修改我的父类 Board,使其适用于派生类的所有其他对象。前任。如果我在 player[1] 的 getTest() 上输入 3,则 player[2] 将能够打印相同的值。这可能吗?

  class Board 
    public:
        int test;
        virtual void getTest() = 0;


;

class Player : public Board
    public:
        int playerNum;
        Player(int _playerNum)
            playerNum = _playerNum;

        
        void printTest()
            cout << "The value of test is: " << Board::test;
        
        void getTest()
            cin >> Board::test;
        

;




int main()


    Player players[] = 1,2;

    players[1].getTest();
    players[0].printTest();


    return 0;

【问题讨论】:

Board::test 应该声明为 static 如果它的状态应该在所有类之间共享 test 设为静态变量。 我会小心推荐static 作为首选。 static 将共享 所有实例,无处不在 的状态——这在设计方面不是很好。 但这似乎是所要求的,不是吗? 确实如此,但在得到你想要的东西和得到你需要的东西之间通常会有很大的不同。 【参考方案1】:

确实可以在派生自Board 的所有实例之间共享状态。

如 cmets 中所述,如果为 Board::test 指定了 static 存储类持续时间,则这将是一个在所有Player 实例和任何其他派生类之间共享的变量来自Board 现在和永远。从技术上讲,变量实际上是 type 的成员,而不是该类型的实例。这会起作用,但是在设计方面,它有一些奇怪的含义。

也就是说,Player::getTest() 是一个非静态成员函数,它设置static 状态,该状态将在Board 的所有派生类之间共享。这可以作为对代码的快速而肮脏的更改,但会导致维护负担和认知开销。例如,如果您在不同的子系统(如 PlayerWidget)中有代码,它们都实现了 Board,您会遇到以下情况:

// subsystem A:
player.getState();

// subsystem B:
widget.printTest(); // not obvious that this comes from the player in "subsystem A"

代码越大,越难理解。

此外,static 变量在跨翻译单元工作时存在问题,这可能导致初始化顺序问题——而且通常是一团糟,不值得与之抗争。


根据您实际打算共享的内容,通常情况下,设计使用明确指示其共享所有权的对象(例如std::shared_ptr)明确声明会更好。

这不会像您最初请求的那样隐式传递给所有内容 - 但这实际上是一件好事,因为您可以明确说明您想要共享哪些数据以及在哪里共享。这也让您可以决定是否存在您不希望在他们之间共享所有内容的情况,您可以这样设计。

您当前代码的一个简单示例将改为:

class Board 
    public:
        virtual void getTest() = 0;
;

class Player : public Board
    public:
        int playerNum;
        std::shared_ptr<int> test;
        Player(int _playerNum, std::shared_ptr<int> _test)
            playerNum = _playerNum;
            test = _test;
        
        void printTest()
            cout << "The value of test is: " << *test;
        
        void getTest()
            cin >> *test;
        
;

int main()
    std::shared_ptr<int> test = std::make_shared<int>(0);

    // explicitly share 'test' between the two players
    Player players[] = Player1,test, Player2,test;

    players[1].getTest();
    players[0].printTest();

    return 0;

这将产生与您最初请求的结果相同的结果,但它显式共享 test,而不是在 static 变量后面隐式执行此操作。

在这里明确声明共享状态还允许您稍后生成更多 Player 对象,这些对象可能与第一个创建的对象共享一组不同的 test 状态(取决于此状态是什么,这可能非常有用) .

总体而言,就可读性和整体认知开销的设计而言,明确您想要共享的数据通常会更好。

【讨论】:

以上是关于从派生类永久更改基类?的主要内容,如果未能解决你的问题,请参考以下文章

c ++派生类更改基类指针

从基类函数派生的类容器

向基类添加默认构造函数会更改派生类型的 sizeof() [重复]

3.继承与派生

如何从基类调用派生类方法?

如何从基类动态创建派生类