MST

星途 面试题库

面试题:C++命名空间的嵌套与多重继承下的构造函数顺序

当存在命名空间嵌套时,其作用域的解析规则是怎样的?在一个具有多重继承关系(例如类A继承自类B和类C,类B和类C又继承自类D)的类体系中,对象构造时各基类构造函数的调用顺序是怎样的?请结合代码示例说明。
39.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

命名空间嵌套时作用域解析规则

  1. 从内到外查找:当在代码中引用一个标识符时,编译器首先在当前局部作用域查找。如果未找到,会依次向外层作用域查找,包括外层命名空间。例如:
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;
}
  1. 使用作用域解析运算符::指定:可以通过::运算符明确指定要使用的命名空间,这样可以直接访问特定命名空间中的标识符,而不遵循从内到外的查找规则。例如:
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类继承自BCBC又继承自D。构造A对象时,输出顺序为:

  1. D constructor (因为B继承自D,先调用D的构造函数)
  2. B constructorB的构造函数)
  3. D constructor (因为C继承自D,再调用D的构造函数)
  4. C constructorC的构造函数)
  5. A constructorA的构造函数)

这表明,先调用B基类及其基类(D)的构造函数,再调用C基类及其基类(D)的构造函数,最后调用A自身的构造函数。