我想问为什么setX函数在这里设置类A中的x成员变量而不是类D中的成员变量x,即使我通过D对象调用setX函数? 编译器是如何做到的?
#include<iostream>
using namespace std;
class A
{
public:
int x;
A() { cout << "A cons" << endl; }
void setX(int i){ x = i; cout << "setxA" << endl; }
void print() { cout << x; }
};
class B : public A
{
public:
int x =30;
B() { cout << "B cons" << endl; }
};
class D : public B {
public:
D() {
cout << "D cons" << endl;
}
void func() {
setX(10);
cout << x << endl;
cout << B::x << endl;
cout << A::x << endl;
}
};
int main()
{
D d;
d.func();
return 0;
}
此代码的输出是 三十 三十 10
答案 0 :(得分:1)
这称为名称隐藏。 A
和B
都有成员x
且两个成员始终存在(您无法以相同的方式访问它们)。 A
了解其成员x
,因此setX
函数确切地设置了此成员A::x
。在B
中,您可以定义另一个隐藏 x
的{{1}}。这意味着,如果你这样做
A::x
或
B obj;
obj.x = 10;
您将同时访问D obj;
obj.x = 10;
(因为B::x
在继承层次结构中较低,因此会隐藏B
。)
以下是您仍然可以使用不同演员表访问A::x
的示例。
A::x
产生输出:
#include <iostream>
struct A {
int x = 0;
void setX(int i) { x = i; }
};
struct B : A {
int x = 20;
};
int main()
{
B obj;
A castToA = static_cast<A>(obj);
A* castToAPtr = reinterpret_cast<A*>(&obj);
std::cout
<< "access via B: " << obj.x << "\n"
<< "access via A: " << castToA.x << "\n"
<< "access via A*: " << castToAPtr->x << "\n"
<< "access via B::(A::x): " << obj.A::x << "\n\n";
obj.setX(100);
std::cout << "set x to 100\n\n";
std::cout
<< "access via B: " << obj.x << "\n"
<< "access via A: " << castToA.x << "\n"
<< "access via A*: " << castToAPtr->x << "\n"
<< "access via B::(A::x): " << obj.A::x << "\n\n";
return 0;
}
答案 1 :(得分:0)
你的B级有一个x而且A有一个X.因此,你有两个x在B! 那你可以从你的B类中删除x吗?
如果您需要两者,可以使用
访问它们你已经做过的B方法中的A :: x或B :: x。
所以你的D类也有x和调用setX调用A的setX方法。在D中,你看到B中的x,它隐藏了你的x,A按预期工作。
你的方法A :: setX不知道你以后派生它。如果要覆盖该方法,B已经定义了一个自己的B :: setX,然后也将在D中使用。
如何覆盖方法并访问派生类中的参数的示例:
class A
{
public:
int x; // A::x
int y = 40; // A::y
// this function only knows about A::x
void setX(int i){ x = i; cout << "setxA" << endl; }
void setY(int i){ y = i; cout << "setyA" << endl; }
};
class B : public A
{
public:
int x =30; // this x ( B::x) hide A::x
int y =50; // this y hides also A::y
// now we override setY from A ( hiding setY from A! )
void setY(int i){ y = i; cout << "setyB" << endl; }
};
class D : public B {
public:
void func() {
setX(10); // Calls A::setX, as A::setX only knows about
// A::x it will access A::x
cout << "X" << std::endl;
cout << x << endl;
cout << B::x << endl;
cout << A::x << endl;
setY(90);
cout << "Y" << std::endl;
cout << y << endl;
cout << B::y << endl;
cout << A::y << endl;
}
};
int main()
{
D d;
d.func();
return 0;
}