2016-07-26 2 views
2

рыть некоторые коды, я нашел способ, с любопытством, чтобы вызвать метод из объекта экземпляра, который я покажу в примере кода ниже:Странный способ вызова метода из объекта экземпляра ...

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()? Почему авторский код использовал первый, а не последний?

Заранее спасибо

ответ

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 
0

Нет разницы между вызовом ex.Example::Print() и ex.Print() в этом примере.

Единственное использование/полезность этого вызова, о котором я могу думать, это с наследованием; Вы можете явно вызвать метод over-ridden в родительском классе, используя этот синтаксис из экземпляра производного класса.

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

Учитывая посланной код, то есть такой же, как:

ex.Print(); 

Это будет иметь значение только если имя скрытие вступает в игру, и вы хотите быть явным о вызове конкретной версии функция.

Ex:

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"; } 
}; 
Смежные вопросы