继承时的变量作用域

发布于 2024-08-09 22:26:29 字数 617 浏览 3 评论 0原文

我在 C++ 中有两个类,一个类继承另一个类:

class A {
public: 
    virtual void Initialize(){
        m_MyString = "Default value";
    }

protected: 
     string m_MyString;
}

class B : public A {
public: 
    void Initialize(){ 
       A::Initialize(); 
       m_MyString = "New Value";
    }
}

上面的 B 类和这个类有区别吗?

class B : public A {
public: 
    void Initialize(){ 
       A::Initialize(); 
       A::m_MyString = "New Value";
    }
}

似乎使用作用域运算符会导致字符串出现垃圾,对吗?我在想当它覆盖时,A::m_MyString 与B::m_MyString 不同。这还有道理吗?

我看到变量在 A 中设置,然后当我们返回 B 时,出现垃圾。这与“隐藏”与覆盖有关吗?

I have two classes in C++, where one inherits from the other:

class A {
public: 
    virtual void Initialize(){
        m_MyString = "Default value";
    }

protected: 
     string m_MyString;
}

class B : public A {
public: 
    void Initialize(){ 
       A::Initialize(); 
       m_MyString = "New Value";
    }
}

Is there a difference between the above class B and this one?

class B : public A {
public: 
    void Initialize(){ 
       A::Initialize(); 
       A::m_MyString = "New Value";
    }
}

It seem using the scoping operator will result in a the string having garbage, correct? I'm thinking when it overrides, the A::m_MyString is different than B::m_MyString. Does this even make sense?

I'm seeing the variable get set in A, then when we return to B, have garbage. This has to do with "hidden" vs. overridden?

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

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

发布评论

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

评论(6

心不设防 2024-08-16 22:26:29

您的代码在很多方面都是无效的。它应该看起来像:

class A { // << errors were here
public: 
    virtual void Initialize(){
        m_MyString = "Default value";
    }

protected: 
     string m_MyString;
}; // << lost ;

class B : public A // << errors were here
{
public: 
    virtual void Initialize(){  // << virtual
       A::Initialize(); // has no effect in the end

       A::m_MyString = "New Value"; // same as `m_MyString = "New Value";`
    }
}; // << lost ;

在上面的代码中,与 m_MyString 没有区别。发布您的实际代码,有错误。

如果您的代码如下所示:

class B : public A
{
public: 
    virtual void Initialize(){
       // here is a difference
       A::m_MyString = "New Value"; 
       m_MyString = "New Value";
    }
protected: 
     string m_MyString; // !!! overridden
};

那么存在差异,因为 B 有两个 m_MyString 实例:A::m_MyStringB: :m_MyString

Your code is not valid in many ways. It should look like:

class A { // << errors were here
public: 
    virtual void Initialize(){
        m_MyString = "Default value";
    }

protected: 
     string m_MyString;
}; // << lost ;

class B : public A // << errors were here
{
public: 
    virtual void Initialize(){  // << virtual
       A::Initialize(); // has no effect in the end

       A::m_MyString = "New Value"; // same as `m_MyString = "New Value";`
    }
}; // << lost ;

In the code above there is no difference with m_MyString. Post your actual code with error.

If your code looks like:

class B : public A
{
public: 
    virtual void Initialize(){
       // here is a difference
       A::m_MyString = "New Value"; 
       m_MyString = "New Value";
    }
protected: 
     string m_MyString; // !!! overridden
};

Then there is a difference because B has two instances of m_MyString: A::m_MyString and B::m_MyString.

叶落知秋 2024-08-16 22:26:29

您是否从 A 的构造函数中调用 Initialize() ?

不建议在构造函数中调用虚方法。例如,如果 A 的构造函数看起来像

A::A() {
  Initialize();
}

B 的 Initialize 方法,则永远不会被调用。

查看您的实际代码会有很大帮助。

Are you calling Initialize() from the constructor of A?

Calling virtual methods in constructors is not recommended. For example, if A's constructor looked like

A::A() {
  Initialize();
}

B's Initialize method would never get called.

Seeing your actual code would help a lot.

趁微风不噪 2024-08-16 22:26:29

B 类的这两个版本之间没有区别。这是您在其中看到垃圾的真实代码吗?

There is no difference between those two versions of class B. Is that the real code that you see garbage in?

灼疼热情 2024-08-16 22:26:29

编译器应该告诉您是否从构造函数调用虚函数。但如果没有,那肯定是有问题的。

我认为你可以在派生类中将虚函数设为final,但也许不行。无论是否显式定义作用域,变量都应该是相同的,除非派生类中有同名的变量。

The compiler should tell you if you're calling a virtual function from a constructor. But if not, that's definitely a problem.

I think you can make a virtual function final in the derived class, but maybe not. The variable should be the same, regardless of whether or not you explicitly define scope, unless you have a variable of the same name in the derived class.

放低过去 2024-08-16 22:26:29

如果您的代码如下所示:

using namespace std;

class A 
{
    public:
        virtual void Initialize()
        {
            m_MyString = "Default value";
        }

    protected:
        string m_MyString;
};

class B : public A 
{
    public:
        void Initialize()
        {
            A::Initialize();
            m_MyString = "New Value";
        }

        void display()
        {
            cout<<m_MyString<<endl;
        }
};

int main()
{
    B b;
    A a;

    b.Initialize();
    b.display();

    return 0;
}

那么您在问题中描述的 B 类的两个版本之间没有区别。我添加显示功能只是为了让值更清晰。根据您给出的类的定义,m_MyString 不会被覆盖。因此,m_MyString 变量将被分配“新值”,即类 A 和 B 将共享变量 m_MyString。

如果您像这样重写 B 类中的 m_MyString

class B : public A 
{
    public:
        void Initialize()
        {
            A::Initialize();
            m_MyString = "New Value";
        }

    void display()
    {
        cout<<m_MyString<<endl;
    }

    protected:
        string m_MyString;
};

那么 B::m_MyString 的值将包含“新值”,而 A::m_MyString 的值将包含“默认值”。

If this is how your code looks:

using namespace std;

class A 
{
    public:
        virtual void Initialize()
        {
            m_MyString = "Default value";
        }

    protected:
        string m_MyString;
};

class B : public A 
{
    public:
        void Initialize()
        {
            A::Initialize();
            m_MyString = "New Value";
        }

        void display()
        {
            cout<<m_MyString<<endl;
        }
};

int main()
{
    B b;
    A a;

    b.Initialize();
    b.display();

    return 0;
}

Then there is no difference between the two versions of the class B that you described in your question. I added the display function just to make the values clear. By the definitions of the class that you have given, the m_MyString is not being overridden. So the m_MyString variable will have "New Value" assigned to it, i.e. both the classes A and B will share the variable m_MyString.

If you override the m_MyString in class B like

class B : public A 
{
    public:
        void Initialize()
        {
            A::Initialize();
            m_MyString = "New Value";
        }

    void display()
    {
        cout<<m_MyString<<endl;
    }

    protected:
        string m_MyString;
};

Then the value of B::m_MyString will contain "New Value" and the Value of A::m_MyString will contain "Default value".

萌逼全场 2024-08-16 22:26:29

<块引用>

似乎使用作用域运算符会导致字符串出现垃圾,对吗?

不,这应该有效,并且在调用 b.Initialize() 后 m_MyString 将具有“新值”。

<块引用>

我在想当它覆盖时,A::m_MyString 与 B::m_MyString 不同。做
这还有道理吗?

不会,当一个类 B 继承另一个类 A 时,类 B 的对象将具有两者的数据成员的并集。在本例中,只有一个 m_MyString,即 A::m_MyString。

<块引用>

我看到变量在 A 中设置,然后当我们返回 B 时,出现垃圾。
这与“隐藏”与覆盖有关吗?

不,m_MyString 只有一个实例。

您绝对需要阅读此内容 - http://www.openrce.org/articles/files /jangrayhood.pdf

It seem using the scoping operator will result in a the string having garbage, correct?

No, this should work and m_MyString will have "New Value" after b.Initialize() is called.

I'm thinking when it overrides, the A::m_MyString is different than B::m_MyString. Does
this even make sense?

No, when a class B inherits another class A, the object of class B will have a union of the data members of the two. In this case, there is only one m_MyString that is A::m_MyString.

I'm seeing the variable get set in A, then when we return to B, have garbage.
This has to do with "hidden" vs. overridden?

No, there is only one instance of m_MyString.

You definitely need to read this - http://www.openrce.org/articles/files/jangrayhood.pdf.

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