更改继承的类'成员变量

发布于 2025-02-04 15:18:36 字数 1579 浏览 3 评论 0原文

背景

我一直在阅读有关继承和弄乱某些代码的信息,我正在尝试更好地了解如何实现虚拟功能,更广泛地,更广泛地更改派生类中的成员变量。这是我到目前为止所拥有的:

代码

#include <iostream>

class Base
{
private:
    int m_value {};
public:

    Base(int value = 5): m_value {value}
    {
    }

    int getValue()
    {
        return m_value;
    }

    virtual void add(int addend)
    {
        m_value = m_value + addend;
    }

};

class Derived: public Base
{
private:
    int m_value {};
public:

    Derived(int value = 5): m_value {value}
    {
    }

    virtual void add(int addend)
    {
        m_value = m_value + addend;
    }
};

int main()
{
    Derived derived {};

    std::cout << derived.getValue() << "\n";
    derived.add(2);
    std::cout << derived.getValue() << "\n";
    

return 0;
}

问题

我希望继承的类在调用add()时更改其成员变量。具体来说,我期望dedived.add(2)使dedived.m_value等于7而不是5。代码>派生.m_value 更改。

我尝试了

我审查了一篇提出类似问题的帖子(继承类的成员功能不会改变继承的基类变量),因此我添加了一个超载的分配运算符:

class Derived: public Base
{
private:
    int m_value {};
public:

    Derived(int value = 5): m_value {value}
    {
    }

    Derived& operator=(const Derived& derived)
    {
        m_value = derived.m_value;
        return *this;

    }

    void add(int addend)
    {
        m_value = m_value + addend;
    }

};

但是,此添加和我尝试过的其他一些变体仍然无法使用。似乎我不明白继承的成员函数如何与他们想象的成员变量相互作用。

Background

I've been reading about inheritance and messing around with some code, and I'm trying to better understand how to implement virtual functions, and more broadly, how to change member variables in derived classes. Here's what I've got so far:

Code

#include <iostream>

class Base
{
private:
    int m_value {};
public:

    Base(int value = 5): m_value {value}
    {
    }

    int getValue()
    {
        return m_value;
    }

    virtual void add(int addend)
    {
        m_value = m_value + addend;
    }

};

class Derived: public Base
{
private:
    int m_value {};
public:

    Derived(int value = 5): m_value {value}
    {
    }

    virtual void add(int addend)
    {
        m_value = m_value + addend;
    }
};

int main()
{
    Derived derived {};

    std::cout << derived.getValue() << "\n";
    derived.add(2);
    std::cout << derived.getValue() << "\n";
    

return 0;
}

Problem

I want the inherited class to change its member variable when add() is called. Specifically, I was expecting derived.add(2) to make derived.m_value equal to 7 as opposed to 5. However, despite my efforts, I can't get derived.m_value to change.

What I've Tried

I reviewed a post that asked a similar question (Member function of inherited class won't change inherited base class variable), and so I added an overloaded assignment operator like this:

class Derived: public Base
{
private:
    int m_value {};
public:

    Derived(int value = 5): m_value {value}
    {
    }

    Derived& operator=(const Derived& derived)
    {
        m_value = derived.m_value;
        return *this;

    }

    void add(int addend)
    {
        m_value = m_value + addend;
    }

};

However, this addition and some other variations I tried still didn't work. It seems like I don't understand how inherited member functions interact with their member variables as well as I thought.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千笙结 2025-02-11 15:18:36

请在下面找到按照您想要的方式工作的样本。我将在下面说明代码。

#include <iostream>

class Base
{
    protected: // HERE change n°1
        int m_value;

    public:
        Base(int value = 5) : m_value{ value }
        {
        }

        int getValue()
        {
            return m_value;
        }

        virtual void add(int addend)
        {
            m_value = m_value + addend;
        }
};

class Derived : public Base
{// HERE change n°2 : no more Derived::m_value which shadows the Base::m_value (this is due to the members of same name)
    public:

        Derived(int value = 5) : Base{ value } // HERE change n°3 : we build the parent class by calling it's constructor so Base::m_value is initialized
        {
        }

        void add(int addend) noexcept override // HERE change n°4
        {
            m_value = m_value + addend;
        }
};

int main()
{
    Derived derived{};

    std::cout << derived.getValue() << "\n";
    derived.add(2);
    std::cout << derived.getValue() << "\n";

    return 0;
}

更改n°1:通过将成员m_value的可见性设置为保护,这意味着我们现在可以在子类中访问它。这是您想要拥有的,以便在OOP角度以阶级的方式和班级之间的方式具有共同的模式/行为和东西。如果您在父级中将其设置为私有,则您将无法在子类中访问它。此语句对成员和方法有效。例如,您可能需要隐藏父母类执行的一些内部管理。

更改n°2:删除子类中M_value的声明,如OLAF所解释的那样,它会遮盖底座:: m_value。

更改n°3:最后,我们在子类构造函数的初始化列表中调用基类的构造函数,因此当您在主机中声明派生变量时,基本实例构造得很好。

更改n°4:您可以将“覆盖键盘”添加到您继承的虚拟方法中。这是编译器的提示,因此它将检查方法签名与父类中的签名相同。这样,如果您写了错误的方法签名,或者在父类中更改方法,则会收到错误/警告。

希望它有帮助

Please find below your sample working the way you want. I'll explain below the code.

#include <iostream>

class Base
{
    protected: // HERE change n°1
        int m_value;

    public:
        Base(int value = 5) : m_value{ value }
        {
        }

        int getValue()
        {
            return m_value;
        }

        virtual void add(int addend)
        {
            m_value = m_value + addend;
        }
};

class Derived : public Base
{// HERE change n°2 : no more Derived::m_value which shadows the Base::m_value (this is due to the members of same name)
    public:

        Derived(int value = 5) : Base{ value } // HERE change n°3 : we build the parent class by calling it's constructor so Base::m_value is initialized
        {
        }

        void add(int addend) noexcept override // HERE change n°4
        {
            m_value = m_value + addend;
        }
};

int main()
{
    Derived derived{};

    std::cout << derived.getValue() << "\n";
    derived.add(2);
    std::cout << derived.getValue() << "\n";

    return 0;
}

Change n°1 : by setting the visibility of the member m_value to protected, it means we now have access to it in the child class. This is what you'd like to have in order to have common patterns/behaviour and stuff between class in an OOP point of view. If you set it private in your parent class, you'll NOT have access to it in the child class. This statement is valid for members and methods. For example, you may want to hide some internal management performed by the parent class.

Change n°2 : remove the declaration of m_value in the child class being given it shadows the Base::m_value as explained by Olaf.

Change n°3 : finally, we call the constructor of the Base class in the init list of the child class constructor, so the base instance is well constructed when you declare a derived variable in your main.

Change n°4 : you can add the override keywoard to the virtual methods you inherit. This is a tips to the compiler so it'll check the method signature is the same than the one in the parent class. This way, if you write a wrong method signature, or if you change your method in the parent class, you'll get an error/warning.

Hope it helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文