抽象
约 765 字大约 3 分钟
2025-06-21
6.抽象概念
在虚函数的后面加上 = 0 那么这个函数就会变成纯虚函数,只要包含一个及以上的纯虚函数的类就叫抽象类(也被叫做接口类),抽象类不能实例出对象,这也是我们第一次接触”抽象“的概念。
抽象类强制子类覆盖虚函数,并且无法实例化出对象,但是可以构建对应类型的指针类型。
#include <iostream>
using namespace std;
class A
{
virtual void function() = 0;
};
class B : public A
{
void function()
{
cout << "I am a function." << endl;
}
};
int main()
{
//A a;//无法创建出对象
A* pa;//允许
B b;//允许
return 0;
}那么有什么用呢?首先父类是抽象类,因此不存在父类对象,这个抽象只是为了多态而设计的出来的,抽象类可以拥有很多子类(Java 就大量使用了这种抽象类)。
#include <iostream>
using namespace std;
class A
{
public:
virtual void function() = 0;
};
class B : public A
{
public:
void function()
{
cout << "B:I am a function." << endl;
}
};
class C : public A
{
public:
void function()
{
cout << "C:I am a function." << endl;
}
};
void func(A* a)
{
a->function();
}
int main()
{
B b;
C c;
b.function();
c.function();
return 0;
}纯虚函数哪怕拥有实体也是纯虚的,因此虚函数的实体没有什么意义。
duo tai de 。。。。
7.2.1.题目一:赋值兼容和强制转化
下面代码输出结果是什么?
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
virtual void f()
{
cout << "A::f()" << endl;
}
};
class B : public A
{
private:
virtual void f()
{
cout << "B::f()" << endl;
}
};
int main()
{
A* pa = (A*)new B;//这里的强制类型转化实际上是多余的,可以直接赋值,因为赋值兼容做出了保障
pa->f();
}7.2.2.题目二:虚表指针的初始化时机
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A() : m_iVal(0)
{
test();
}
virtual void func()
{
std::cout << m_iVal << ' ';
}
void test()
{
func();
}
public:
int m_iVal;
};
class B : public A
{
public:
B()
{
test();
}
virtual void func()
{
++m_iVal;
std::cout << m_iVal << ' ';
}
};
int main(int argc, char* argv[])
{
A* p = new B;
//1. 使用 new 调用 B 类的构造函数 B(B* this)
//
//2. 在子类构造函数 B(B* this) 中默认先利用切片调用父类构造函数 A(A* this),
// 初始化了子类内继承的 m_iVal 为 0,而内部又去调用 test(A* this),
// 这里无法发生多态(此时还在 B 类对象还在构造阶段,而其虚表指针又是初始化列表最后一个初始化的)
// 因此调用 func(A* this),此时 m_iVal 为 0,并且打印出 "0 "
//
//3. B(B* this)的初始化列表走完了,此时 B 类对象内部就有了虚表指针。
// 而子类构造函数 B(B* this) 内部的 test() 由于继承,
// 直接调用父类内部的 test(A* this),这里可以发生多态,
// 因此内部调用 func() 调用的是子类的 func(),m_iVal 变为 1,并且打印 "1 "
p->test();
//4. 这里由于继承直接调用父类的 test(A* this),内部发生多态调用 func(A* this),
// 则 m_iVal 变为 2,打印"2 "
return 0;
}更新日志
2025/11/24 07:31
查看所有更新日志