某次电话面试的前半段,公司就不说了。
面试官: 你的编程语言是什么?
我以为是直接开始编程了。于是说:C++吧。
面试官: 那我们来问几个问题吧。
我…
(一直在看Java的面试题啊,C++一点没看!唯一一次系统的学,就是大一的时候考计算机二级的时候看了一个星期。并且也只看了一下语法,什么虚函数,OOP的哪儿懂啊。)
以下画面惨不忍睹,我就只说问题了。
- 构造函数和析构函数能不能是虚函数?
- 什么是构造函数和析构函数?
- 什么是虚函数?
- C++多态的你了解吗?
- 深拷贝和浅拷贝你了解吗?
总之就没答上什么。
为了预防这种事情,我赶紧把最新的简历上的会C++改成了会C。但是有的已经投出去了,不能改了。所以现在C++相关的也得看一下了。
经过一番学习,现在的我已经稍微懂一点了。
虚函数
前4个问题,可以说就是围绕虚函数展开的。
先说多态: 多态就是一个名字,多种功能。面试的时候,我只知道函数重载和运算符重载。但是,这是编译时的。还有运行时的,这就是虚函数的用处。
#include <iostream>
#include <cstdio>
using namespace std;
class C1 {
public:
void print() {
puts("c1");
}
};
class C2 : public C1 {
public:
void print() {
puts("c2");
}
};
int main() {
C1* c1 = new C1();
C2* c2 = new C2();
C1* c3 = new C2();
c1->print();
c2->print();
c3->print();
return 0;
}
对于这段代码,输出的是c1 c2 c1
可见c3虽然用了C2的构造函数,但实际上还是C1。这是因为编译时,已经把c3规定成是C1了。
但是我们使用虚函数
#include <iostream>
#include <cstdio>
using namespace std;
class C1 {
public:
virtual void print() {
puts("c1");
}
};
class C2 : public C1 {
public:
void print() {
puts("c2");
}
};
int main() {
C1* c1 = new C1();
C2* c2 = new C2();
C1* c3 = new C2();
c1->print();
c2->print();
c3->print();
return 0;
}
这样就可以输出c1 c2 c2了
可以看出C1的指针c1和c3一个指向C1,一个指向C2
同一种类型指向两个不同的类,这就是多态!
那这种情况呢?
#include <iostream>
#include <cstdio>
using namespace std;
class C1 {
public:
virtual void print() {
puts("c1");
}
void print2() {
puts("2-c1");
}
};
class C2 : public C1 {
public:
void print() {
puts("c2");
}
void print2() {
puts("2-c2");
}
};
int main() {
C1* c1 = new C1();
C2* c2 = new C2();
C1* c3 = new C2();
c1->print();
c2->print();
c3->print();
c3->print2();
return 0;
}
一个调用c3的虚函数,一个调用非虚函数
输出:
c1 c2 c2 2-c1,可见只有有虚函数,才会调用子类方法。
构造函数和析构函数能不能是虚函数?
参考这个: http://blog.csdn.net/woyaowenzi/article/details/2310710,写得非常好
答案是:
构造函数不能。
析构函数能,且最好要。否则不会调用派生类的析构函数,导致不能正常销毁。
深拷贝和浅拷贝
http://www.learncpp.com/cpp-tutorial/915-shallow-vs-deep-copying/
简单的来说,就是一个全部复制,一个只复制指针。
感觉自己基础知识薄弱啊,得好好学习。