从实例对象调用方法的奇怪方法...

时间:2016-07-26 19:30:54

标签: c++ class object methods

挖掘一些代码,我发现了一种奇怪的方式从实例对象中调用一个方法,我将在下面的示例代码中显示:

class Example{
public:
  void Print(){ std::cout << "Hello World" << std::endl;}
};

int main(){
  Example ex;
  ex.Example::Print(); // Why use this notation instead of just ex.Print();
  return 0;
}

ex.Example :: Print()与标准方式 ex.Print()之间是否存在任何行为差异?为什么作者的代码使用的是前者而不是后者?

提前致谢

3 个答案:

答案 0 :(得分:9)

不同之处在于ex.Example::Print()指定您希望类Print()中定义的Example版本。在这个特定的例子中,没有区别。但是,请考虑以下事项:

#include <iostream>

class One {
    int i;

  public:
    One(int ii) : i(ii) {}
    virtual void print() { std::cout << i << std::endl; }
};

class Two : public One {
    int j;

  public:
    Two(int ii, int jj) : One(ii), j(jj) {}
    void print() override {
        One::print();
        std::cout << j << std::endl;
    }
};

class Three : public Two {
    int k;

  public:
    Three(int ii, int jj, int kk) : Two(ii, jj), k(kk) {}
    void print() override {
        Two::print();
        std::cout << k << std::endl;
    }
};

int main() {
    Three four(1, 2, 3);

    four.print();
    std::cout << std::endl;

    four.One::print();
    std::cout << std::endl;
    four.Two::print();
    std::cout << std::endl;
    four.Three::print();
    std::cout << std::endl;
}

输出将是:

1
2
3

1

1
2

1
2
3

答案 1 :(得分:5)

 ex.Example::Print(); // Why use this notation instead of just ex.Print();

鉴于发布的代码,与以下内容相同:

ex.Print();

只有在名称隐藏发挥作用并且您希望明确调用特定版本的函数时,它才会有所作为。

例如:

struct Foo
{
   void Print() const { std::cout << "Came to Foo::Print()\n"; }
};

struct Bar : Foo
{
   void Print() const { std::cout << "Came to Bar::Print()\n"; }
};

int main()
{
   Bar b;
   b.Print(); // Calls Bar::Print()
   b.Foo::Print();  // Calls Foo::Print()
}

这只是事情运作的机制。作为设计选择,最好使用virtual函数:

struct Foo
{
   virtual void Print() const { std::cout << "Came to Foo::Print()\n"; }
};

struct Bar : Foo
{
   virtual void Print() const { std::cout << "Came to Bar::Print()\n"; }
};

答案 2 :(得分:0)

在此示例中,调用ex.Example::Print()ex.Print()之间没有区别。

我能想到的这个调用的唯一用途/好处是继承;您可以使用派生类的实例使用此语法在父类中显式调用over-ridden方法。