class A{
int var;
public:
virtual void foo(); // sets var
void bar(); // reads var and displays value
};
class B : public A{
int var;
public:
void foo();
};
void A::bar(){
printf("%d",var);
}
void B::foo(){
var = 42;
}
void func(){
B myObj;
myObj.foo();
myObj.bar();
}
class A2{
virtual void foo(); // sets var
public:
int var;
void bar(); // read var and displays value
};
class B2 : public A2{
public:
void foo();
};
foo
致电func
后,foo会设置A::var
还是B::var
?bar
中的func
来电bar
会A::var
或B::var
?var
的实例,是否需要在A
中将A
声明为数据成员?A2
和B2
是否与A
和B
的效果相同?答案 0 :(得分:2)
关于1.和2.由于foo不可见(并且A::foo
没有身体),因此出现错误:
class B : public A{
int var;
void foo();
};
无论如何,因为你没有通过指针/引用来调用它
void func(){
B myObj;
myObj.foo(); // No polymorphic behavior here, B::foo is called
myObj.bar(); // the same, but A::bar is called since B hasn't one
}
关于3.和4.如果base和derived类都有一个具有相同名称的变量,派生的' s隐藏基类的名称,并且通过派生对象的每次访问都将导致派生的正在设置/调用(除非明确地执行base::var
)。如果只有一个人拥有它,它就会很好,并且它们都会调用相同的版本(前提是它可见/可访问)。在上面的示例中:
void A::bar(){
std::cout << var; // This will output an uninitialized A::var!
}
void B::foo(){
var = 42; // B's var hides A's var so this only sets the derived one's
}
修改:在A2
和B2
的情况下,A2::var
只有一个实例,即使是派生类,每次访问它都会引用基础一,例如
class A2{
virtual void foo() = 0;
public:
int var;
void bar() {
std::cout << var; // Will correctly output 42
}
};
class B2 : public A2{
public:
void foo() {
var = 42; // Sets the common A2::var variable
};
};
void func2(){
B2 myObj;
myObj.foo();
myObj.bar();
}
看看并研究以下内容: Example
答案 1 :(得分:1)
修复了注释中提到的私有问题后,还提供了A :: foo的实现,以避免&#34; undefined vtable&#34;错误,然后你会看到你正在调用B :: foo,它只留下A :: var,但是bar打印出A :: var。
在派生类中使用相同的变量名称相当愚蠢,但我会考虑到我未来的混淆要求。
A2和B2看起来不那么超现实。
答案 2 :(得分:1)
在func中调用foo后,foo会设置A :: var或B :: var?
foo将设置B :: var
func()中的在func中调用bar会禁止读取A :: var或B :: var?
栏将返回A :: var,它将为零或未定义
如果没有A的实例,是否需要将var声明为A中的数据成员 会被创造出来吗?
是的,因为它是返回变量的void A :: bar()。
类声明A2和B2是否与A和A具有相同的效果 乙
不,A2 :: bar和B2 :: bar将返回相同的var(42)。
答案 3 :(得分:0)
- 在func中调用foo后,foo会设置A :: var或B :: var?
醇>
foo()
是虚拟的,myObj
的动态(实际上是静态)类型是B
,因此调用它B::foo()
,设置{{1} }}
请注意,在这种情况下,B::var
无效,因为您没有使用多态性。
- 在func中调用bar会禁止读取A :: var或B :: var?
醇>
它会显示virtual
。
- 如果不创建A的实例,是否需要将var声明为A中的数据成员?
醇>
您需要让我认为A::var
虚拟,或者A::bar()
在某个时刻调用B::foo()
来设置基本成员变量。
- 类声明A2和B2是否与A和B的效果相同?
醇>
您希望他们以何种方式与众不同?