下面描述中,错误的是()
基类定义的public成员在公有继承的派生类中可见,也能在类外被访问
基类定义的public和protected成员在私有继承的派生类中可见,在类外可以被访问
基类定义的public和protected成员在保护继承的派生类中不可见
基类定义的protected成员在protected继承的派生类中可见,也能在类外被访问
A. public成员可以被类中的函数、友元函数、类的对象、派生类访问。
B.私有继承时,基类的public和protected成员都变成派生类的private类型,因此不可被类外访问。
C.保护继承时,基类的public和protected成员都变成派生类的protected类型,可以被派生类访问。
D.protected成员可以被类中的函数、友元函数、派生类访问,不能被类的对象访问,因此不能在类外被访问。
1 以下程序输出结果是____
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
class
A
{
public
:
A ():m_iVal(0){test();}
virtual
void
func() { std::cout<<m_iVal<<‘ ’;}
void
test(){func();}
public
:
int
m_iVal;
};
class
B :
public
A
{
public
:
B(){test();}
virtual
void
func()
{
++m_iVal;
std::cout<<m_iVal<<‘ ’;
}
};
int
main(
int
argc ,
char
* argv[])
{
A*p =
new
B;
p->test();
return
0;
}
0 1 2
本问题涉及到两个方面:
1.C++继承体系中构造函数的调用顺序。
2.构造函数中调用虚函数问题。
C++继承体系中,初始化时构造函数的调用顺序如下
(1)任何虚拟基类的构造函数按照他们被继承的顺序构造
(2)任何非虚拟基类的构造函数按照他们被继承的顺序构造
(3)任何成员对象的函数按照他们声明的顺序构造
(4)类自己的构造函数
据此可知 A*p = new
B;先调用A类的构造函数再调用B类的构造函数。
构造函数中调用虚函数,虚函数表现为该类中虚函数的行为,即在父类构造函数中调用虚函数,虚函数的表现就是父类定义的函数的表现。why?原因如下:
假设构造函数中调用虚函数,表现为普通的虚函数调用行为,即虚函数会表现为相应的子类函数行为,并且假设子类存在一个成员变量int a;子类定义的虚函数的新的行为会操作a变量,在子类初始化时根据构造函数调用顺序会首先调用父类构造函数,那么虚函数回去操作a,而因为a是子类成员变量,这时a尚未初始化,这是一种危险的行为,作为一种明智的选择应该禁止这种行为。所以虚函数会被解释到基类而不是子类。
据此可以得到答案C正确
2
则构造函数中,成员变量一定要通过初始化列表来初始化的是__bc__。
有一个类B继承自类A,他们数据成员如下:
引用,const成员变量,基类构造函数 一定要通过初始化列表来实现。 static类型不是类对象成员,不需要通过初始化列表来初始化
构造函数初始化时必须采用初始化列表一共有三种情况,
3 假定CSomething是一个类,执行下面这些语句之后,内存里创建了__6__个CSomething对象。
|