C++ 面试题:多态、继承、构造函数调用顺序
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类中的a和b的值。d.Show()输出d对象中的x和y的值,并没有修改。d.f1()调用了A类中的Show函数,输出A类中a和b的值,此时a和b的值已经被修改为4和7。
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
解析:
B和C类都虚继承了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类继承了A、B和C类,它们的构造函数调用顺序与它们在类继承列表中的顺序一致。D类的构造函数会隐式调用A、B和C类的构造函数。
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
解析:
B和C类都虚继承了A类,因此D类中只有一个A类的副本。- 构造函数的调用顺序为:
A->B->C->D。 - 虚继承可以避免在多层继承中出现多个基类副本,从而节省内存空间。
希望这些解析能够帮助你更好地理解 C++ 中的多态、继承和构造函数调用顺序。
原文地址: https://www.cveoy.top/t/topic/oaq7 著作权归作者所有。请勿转载和采集!