面试题答案
一键面试命名空间嵌套时作用域解析规则
- 从内到外查找:当在代码中引用一个标识符时,编译器首先在当前局部作用域查找。如果未找到,会依次向外层作用域查找,包括外层命名空间。例如:
namespace Outer {
int num = 10;
namespace Inner {
int num = 20;
void printNum() {
// 首先查找当前局部作用域,无定义
// 然后查找Inner命名空间,找到num = 20
std::cout << num << std::endl;
}
}
}
int main() {
Outer::Inner::printNum();
return 0;
}
- 使用作用域解析运算符
::
指定:可以通过::
运算符明确指定要使用的命名空间,这样可以直接访问特定命名空间中的标识符,而不遵循从内到外的查找规则。例如:
namespace Outer {
int num = 10;
namespace Inner {
int num = 20;
void printOuterNum() {
// 使用Outer::num明确访问Outer命名空间中的num
std::cout << Outer::num << std::endl;
}
}
}
int main() {
Outer::Inner::printOuterNum();
return 0;
}
多重继承时基类构造函数调用顺序
在多重继承中,基类构造函数的调用顺序按照它们在派生类定义中继承列表的顺序,而不是按照基类的继承层次结构。例如:
class D {
public:
D() { std::cout << "D constructor" << std::endl; }
};
class B : public D {
public:
B() { std::cout << "B constructor" << std::endl; }
};
class C : public D {
public:
C() { std::cout << "C constructor" << std::endl; }
};
class A : public B, public C {
public:
A() { std::cout << "A constructor" << std::endl; }
};
int main() {
A a;
return 0;
}
上述代码中,A
类继承自B
和C
,B
和C
又继承自D
。构造A
对象时,输出顺序为:
D constructor
(因为B
继承自D
,先调用D
的构造函数)B constructor
(B
的构造函数)D constructor
(因为C
继承自D
,再调用D
的构造函数)C constructor
(C
的构造函数)A constructor
(A
的构造函数)
这表明,先调用B
基类及其基类(D
)的构造函数,再调用C
基类及其基类(D
)的构造函数,最后调用A
自身的构造函数。