问题 C ++:访问父方法和变量


我应该以哪种方式访问​​此父方法和父变量?

class Base
{
public:
    std::string mWords;
    Base() { mWords = "blahblahblah" }
};

class Foundation
{
public:
    Write( std::string text )
    {
        std::cout << text;
    }
};

class Child : public Base, public Foundation
{
    DoSomething()
    {
        this->Write( this->mWords );
        // or
        Foundation::Write( Base::mWords );
    }
};

谢谢。

编辑:如果有歧义怎么办?


8021
2017-12-24 00:45


起源



答案:


您在代码中使用的两种语法(this->... 只有在存在歧义或其他名称查找问题时才需要特殊的名称,例如名称隐藏,模板基类等。

当没有歧义或其他问题时,您不需要任何这些语法。你需要的只是一个简单的不合格的名字,比如 Write 在你的例子中。只是 Write不是 this->Write 并不是 Foundation::Write。这同样适用于 mWords

即在你的具体例子中一个普通的 Write( mWords ) 会工作得很好。


为了说明上述情况,如果你的 DoSomething 方法了 mWords 参数,如

DoSomething(int mWords) {
  ...

然后这个本地 mWords 参数将隐藏继承的类成员 mWords 而且你必须使用其中之一

DoSomething(int mWords) {
  Write(this->mWords);
}

要么

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

正确地表达你的意图,即突破隐藏。


如果你的 Child 上课也有自己的 mWords 成员,如

class Child : public Base, public Foundation
{
  int mWords
  ...

那么这个名字就会隐藏继承的名字 mWords。该 this->mWords 在这种情况下的方法不会帮助你取消隐藏正确的名称,你必须使用限定名称来解决问题

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

如果你的两个基类都有 mWords 成员,如

class Base {
public:
  std::string mWords;
  ...
};

class Foundation {
public:
  int mWords;
  ...

然后在 Child::DoSomething 该 mWords 名字会含糊不清,你必须这样做

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

解决歧义。


但是,再次,在您的具体示例中,没有歧义,没有名称隐藏所有这些都是完全没必要的。


11
2017-12-24 01:33



说得通。谢谢!


答案:


您在代码中使用的两种语法(this->... 只有在存在歧义或其他名称查找问题时才需要特殊的名称,例如名称隐藏,模板基类等。

当没有歧义或其他问题时,您不需要任何这些语法。你需要的只是一个简单的不合格的名字,比如 Write 在你的例子中。只是 Write不是 this->Write 并不是 Foundation::Write。这同样适用于 mWords

即在你的具体例子中一个普通的 Write( mWords ) 会工作得很好。


为了说明上述情况,如果你的 DoSomething 方法了 mWords 参数,如

DoSomething(int mWords) {
  ...

然后这个本地 mWords 参数将隐藏继承的类成员 mWords 而且你必须使用其中之一

DoSomething(int mWords) {
  Write(this->mWords);
}

要么

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

正确地表达你的意图,即突破隐藏。


如果你的 Child 上课也有自己的 mWords 成员,如

class Child : public Base, public Foundation
{
  int mWords
  ...

那么这个名字就会隐藏继承的名字 mWords。该 this->mWords 在这种情况下的方法不会帮助你取消隐藏正确的名称,你必须使用限定名称来解决问题

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

如果你的两个基类都有 mWords 成员,如

class Base {
public:
  std::string mWords;
  ...
};

class Foundation {
public:
  int mWords;
  ...

然后在 Child::DoSomething 该 mWords 名字会含糊不清,你必须这样做

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

解决歧义。


但是,再次,在您的具体示例中,没有歧义,没有名称隐藏所有这些都是完全没必要的。


11
2017-12-24 01:33



说得通。谢谢!


由于没有命名冲突,只需使用 Write(mWords)。如果您有局部变量冲突,或者隐藏名称,请使用另外2个。


0
2017-12-24 00:54



如果有冲突,您建议我使用哪种方法?
什么是“当名字被隐藏”时你是什么意思?
如果它是局部变量和成员变量之间的冲突(例如,您的类具有成员变量 i,您的方法也使用局部变量 i), 使用 this。如果 A 声明一个函数 f,和 B 继承 A 并宣布 f 还有,你想打电话 A的 f 从 B,然后使用 A::f。 - lijie


我认为这是最常见的方法:

Write(mWords);

除非你遇到歧义。

如果存在歧义或阴影,因为你想要(特定)基类中的某些东西但是另一个基类(或这个类)中的东西隐藏它,那么使用 Base::name 句法。

如果局部变量遮蔽了您的某个成员,则使用 this->虽然一般来说你应该尽量避免这种情况。 (即:尽量避免命名本地人,使他们影子成员)

我想有一种看待它的方法是使用第一种有效的方法并做你想做的事情:

  1. name
  2. this->name
  3. Base::name

0
2017-12-24 00:52



是的,我可能要处理含糊不清的问题......我将在原帖中澄清。