派生类的虚函数
派生类继承父类的虚函数,派生类中的这个函数即使没有声明virtual, 也是虚函数。对于虚函数,可以重写实现多态。重写函数是指派生类具有和父类一样的函数名和参数的函数,那么在子类调用这类函数的时候,就会隐藏父类的函数。而在虚函数里面则通过对派生类的引用,既可以调用父类的函数也可以是子类的函数,形成多态。调用父类函数的时候, 必须指明作用域:Derive->Base::method();
其中,父类必须定义虚析构函数,这样在派生类进行析构的时候(指针初始化),才会正确析构父类的指针(堆存储)。
虚函数的使用:
虚函数和普通函数重写的不同:通过对定义父类的指针类型或者是引用,在运行的时候,虚函数的调用结果根据指针所指对象来定,这也就是多态----动态编译;静态编译指的是在运行前就已经编译:比如说普通函数,非虚函数;这里尽管是指向子类的指针,但是调用相同的方法的时候,仍然是实现的父类方法。
- 拥有纯虚函数的类叫做抽象类,抽象类不可以实例化。
- 纯虚函数不可以定义函数体。
- 抽象类不仅可以有纯虚函数也可以有可以定义的函数。
- 子类如果不实现父类的纯虚函数,则子类变为抽象类。
构造函数:
如果显示的写出构造函数,那么编译器就不会自己再创建一个默认构造函数。这个时候派生类就在自己的构造函数里必须显式调用父类的构造方法。
另外,即使自己写出的是无参数构造函数,那也需要在头文件里声明。无参构造函数也是默认构造函数,不需要再写 class() = default; 会出现 overload 报错。
tip: 在实例化对象的时候,如果是自己写的构造函数,那么在初始化的时候,不需要添加括号。
以下是代码的相应实现:
class1:
#include "classfirst.h"
#include <iostream>
using namespace std;
namespace class1 {
classfirst::classfirst(int c) {
count = c;
}
int classfirst::getcount() {
return count;
}
void classfirst::add() {
count++;
}
void classfirst::parentMethod() {
cout << "this is the method of the first class" << endl;
}
//void parent()
}
#pragma once
namespace class1 {
class classfirst {
public:
classfirst(int count);
classfirst() = default;// default constructot to provide the derive class the initialization.
virtual int getcount();
void add();
virtual void parentMethod();
private:
int count=0;
};
}
class2:
#include "classsecond.h"
#include <iostream>
namespace class2 {
// when creat a derived class,the constructor method must initialize the construct method of the base class
classsecond::classsecond():count(6)
{
//count = c;
}
int classsecond::getcount() {
return count;
}
void classsecond::add() {
count++;
}
void classsecond::parentMethod() {
std::cout << "this is the method of the second class" << std::endl;
}
void classsecond::parentMethod(int i) {
std::cout << "TEST FOR " << i << std::endl;
}
}
这里的class1 有默认构造函数,所以在构建class2 的构造函数时,没有明确写出初始化class1的构造函数初始化。否则,需要这样写 :classsecond::classsecond():count(6),classfirst(2)
就不会提示:error : no exiting class1 default constructor.
这里就相当于python中的__init__()方法里面的super(name,self).__init__()
方法,用来初始化父类的变量。
#pragma once
#include "classfirst.h"
namespace class2{
class classsecond: public class1::classfirst {
public:
//classsecond(int count);
//classsecond() = default;
classsecond();
int getcount();
void add();
void parentMethod();
void parentMethod(int i=8);
private:
int count;
};
}
main.cc:
int main() {
class1::classfirst A(5);
cout << A.getcount() << endl;
//class2::classsecond B;
//cout << B.getcount() << endl;
//A.parentMethod();
//B.parentMethod();
//class1::classfirst* b = new class2::classsecond();
//b->add();// call the base method, cause the non-virtual method
cout << b->getcount() << endl;
b->parentMethod();// the derived method , virtual method;
//b->parentMethod();
//std::thread B = thread(thB);
//std::thread A = thread(thA);
//while (1);
return 0;
}