挖掘一些代码,我发现了一种奇怪的方式从实例对象中调用一个方法,我将在下面的示例代码中显示:
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()之间是否存在任何行为差异?为什么作者的代码使用的是前者而不是后者?
提前致谢
答案 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方法。