C++ 面试题:多态、继承、构造函数调用顺序

以下是一些 C++ 面试题,涉及多态、继承、构造函数调用顺序等重要概念,并给出详细解析和运行结果,帮助你理解这些知识点的应用场景和实现原理。

1. 运行结果

#include <iostream.h>
void sub(int x, int y, int *z) {
 *z = y + x;
}
void main() {
 int a, b, c;
 sub(8, 4, &a); 
 sub(6, a, &b); 
 sub(a, b, &c); 
 cout << a << "," << b << "," << c << endl;
}

运行结果:

12,18,30

解析:

  • sub 函数的作用是将两个整数相加并将结果存储到指向第三个整数的指针指向的内存位置。
  • main 函数中,三次调用 sub 函数,依次将 a, b, c 的值计算出来,并输出。

2. 运行结果

#include <iostream.h>
class A {
private:
 int a, b;
public:
 A(int i, int j) { a = i; b = j; }
 void Move(int x, int y) { a += x; b += y; }
 void Show() { cout << "( " << a << ", " << b << " )" << endl; }
};
class B : private A {
public:
 B(int i, int j, int k, int l) : A(i, j) { x = k; y = l; }
 void Show() { cout << x << " ," << y << endl; }
 void fun() { Move(3,5); }
 void f1() { A :: Show(); }
private:
 int x, y;
};
void main() {
 A e(1, 2);
B d(3, 4, 5, 6);
 e.Show();
 d.fun();
 d.Show();
 d.f1();
}

运行结果:

( 1, 2 )
5 ,6
( 4, 7 )

解析:

  • B 类私有继承了 A 类,因此 B 类只能通过 A 类中的公有成员函数访问 A 类中的私有成员。
  • d.fun() 调用 Move 函数,修改了 d 对象中继承的 A 类中的 ab 的值。
  • d.Show() 输出 d 对象中的 xy 的值,并没有修改。
  • d.f1() 调用了 A 类中的 Show 函数,输出 A 类中 ab 的值,此时 ab 的值已经被修改为 47

3. 运行结果

#include <iostream.h>
#include <string.h>
class Student {
private:
 char name[20];
 int age;
public:
 Student() { strcpy(name, ""); age = 0; }
 Student(char *n, int a) { strcpy(name, n); age = a; }
 void Show() { cout << "Name: " << name << ", Age: " << age << endl; }
};
class Undergraduate : public Student {
private:
 char major[20];
public:
 Undergraduate() { strcpy(major, ""); }
 Undergraduate(char *n, int a, char *m) : Student(n, a) { strcpy(major, m); }
 void Show() { Student :: Show(); cout << "Major: " << major << endl; }
};
void main() {
 Student s("Tom", 20);
 Undergraduate u("Jerry", 19, "Computer Science");
 s.Show();
 u.Show();
}

运行结果:

Name: Tom, Age: 20
Name: Jerry, Age: 19
Major: Computer Science

解析:

  • Undergraduate 类公有继承了 Student 类,并添加了一个 major 成员变量,用于存储专业信息。
  • u.Show() 函数调用了 Student 类中的 Show 函数,并输出 Undergraduate 类中 major 的值。

4. 运行结果

#include <iostream.h>
class A {
public:
 A(int i) { cout << "A-" << i << endl; }
};
class B : virtual public A {
public:
 B(int i, int j) : A(i) { cout << "B-" << j << endl; }
};
class C : virtual public A {
public:
 C(int i, int j) : A(i) { cout << "C-" << j << endl; }
};
class D : public B, public C {
public:
 D(int a, int b, int c, int d) : A(a), B(b, c), C(b, d) { cout << "D" << endl; }
};
void main() {
 D d(1, 2, 3, 4);
}

运行结果:

A-1
B-3
C-4
D

解析:

  • BC 类都虚继承了 A 类,这避免了在 D 类中出现 A 类的多个副本。
  • 构造函数的调用顺序为:首先调用最基类的构造函数,然后依次调用派生类的构造函数。
  • 因为 D 类中同时继承了 B 类和 C 类,所以 B 类和 C 类的构造函数都需要调用一次。

5. 运行结果

#include <iostream.h>
class Base {
public:
 virtual void Show() { cout << "Base" << endl; }
};
class Derived : public Base {
public:
 void Show() { cout << "Derived" << endl; }
};
void main() {
 Base *p = new Derived;
 p->Show();
}

运行结果:

Derived

解析:

  • Base 类中的 Show 函数被声明为 virtual 函数,表示这是一个虚函数。
  • p 指针指向一个 Derived 类的对象,因此 p->Show() 会调用 Derived 类中的 Show 函数,而不是 Base 类中的 Show 函数。

6. 运行结果

#include <iostream.h>
class A {
public:
 A(int i) { cout << "A-" << i << endl; }
};
class B : public A {
public:
 B(int i, int j) : A(i) { cout << "B-" << j << endl; }
};
class C : public A {
public:
 C(int i, int j) : A(i) { cout << "C-" << j << endl; }
};
class D : public B, public C {
public:
 D(int a, int b, int c, int d) : A(a), B(a, b), C(a, c) { cout << "D-" << d << endl; }
};
void main() {
 D d(1, 2, 3, 4);
}

运行结果:

A-1
B-2
C-3
D-4

解析:

  • D 类继承了 B 类和 C 类,而 B 类和 C 类都继承了 A 类。
  • 由于 D 类中没有对 A 类的构造函数进行显示的调用,因此 D 类的构造函数会隐式调用 A 类的构造函数,并且调用顺序为:A -> B -> C -> D

7. 运行结果

#include <iostream.h>
class A {
public:
 A() { cout << "A" << endl; }
};
class B {
public:
 B() { cout << "B" << endl; }
};
class C {
public:
 C() { cout << "C" << endl; }
};
class D : public C, public B, public A {
public:
 D() { cout << "D" << endl; }
};
void main() {
 D d;
}

运行结果:

A
B
C
D

解析:

  • D 类继承了 ABC 类,它们的构造函数调用顺序与它们在类继承列表中的顺序一致。
  • D 类的构造函数会隐式调用 ABC 类的构造函数。

8. 运行结果

#include <iostream.h>
class Base {
public:
 virtual void Show() { cout << "Base" << endl; }
};
class Derived : public Base {
public:
 void Show() { cout << "Derived" << endl; }
};
void fun(Base *p) {
 p->Show();
}
void main() {
 Base *p = new Derived;
 fun(p);
}

运行结果:

Derived

解析:

  • fun 函数接收一个 Base 类的指针作为参数,然后调用 Show 函数。
  • 由于 Show 函数被声明为 virtual 函数,因此 p->Show() 会根据指针指向的对象类型来决定调用哪个 Show 函数。
  • 因为 p 指针指向一个 Derived 类的对象,因此 p->Show() 会调用 Derived 类中的 Show 函数。

9. 运行结果

#include <iostream.h>
class A {
public:
 A() { cout << "A" << endl; }
};
class B : virtual public A {
public:
 B() { cout << "B" << endl; }
};
class C : virtual public A {
public:
 C() { cout << "C" << endl; }
};
class D : public B, public C {
public:
 D() { cout << "D" << endl; }
};
void main() {
 D d;
}

运行结果:

A
B
C
D

解析:

  • BC 类都虚继承了 A 类,因此 D 类中只有一个 A 类的副本。
  • 构造函数的调用顺序为:A -> B -> C -> D
  • 虚继承可以避免在多层继承中出现多个基类副本,从而节省内存空间。

希望这些解析能够帮助你更好地理解 C++ 中的多态、继承和构造函数调用顺序。

C++ 面试题:多态、继承、构造函数调用顺序

原文地址: https://www.cveoy.top/t/topic/oaq7 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录