当前位置: 首页 > 新闻动态 > 网络资讯

C++ 抽象类能实例化吗 C++ 纯虚函数对对象创建的限制【规则】

作者:冰火之心 浏览: 发布日期:2026-01-29
[导读]:抽象类因含纯虚函数(=0)而无法实例化,此为编译期强制检查;派生类须显式实现所有继承的纯虚函数且签名一致,才成为具体类。
抽象类因含纯虚函数(= 0)而无法实例化,此为编译期强制检查;派生类须显式实现所有继承的纯虚函数且签名一致,才成为具体类。

抽象类不能直接实例化,编译器会报错 error: cannot declare variable 'x' to be of abstract type

抽象类只要包含至少一个 pure virtual function(纯虚函数),就失去构造具体对象的能力。这不是运行时限制,而是编译期强制检查——哪怕纯虚函数有实现体,只要声明为 = 0,该类就不可实例化。

常见错误场景:

  • 误写 Base obj;,其中 Basevirtual void f() = 0;
  • 试图用 new Base 创建堆对象,同样失败
  • 派生类未重写全部纯虚函数,仍属抽象类,也无法实例化

纯虚函数定义本身不阻止派生类实例化,但继承链必须“补全”所有纯虚接口

派生类只有在**显式提供所有继承来的纯虚函数的非纯虚实现**后,才成为具体类(concrete class)。注意:重写必须是 public 且签名完全一致(返回类型协变除外)。

实操要点:

  • 派生类中用 override 显式标注,避免因拼写/const/volatile 不匹配导致隐式继承纯虚性
  • 基类纯虚函数有默认实现(如 virtual void log() = 0 { std::cout ),不影响抽象性,也不免除派生类实现义务
  • 多重继承时,每个父类的纯虚函数都需覆盖,缺一不可

想绕过限制?只能通过指针或引用操作抽象类对象,且目标必须是具体派生类

抽象类的真正用途是作为接口规范,实际对象必须由子

类创建。典型模式:

Base* p = new Derived();  // OK:指向具体对象
Base& r = *p;             // OK:绑定到具体对象
Base b;                   // ERROR:禁止

关键点:

  • new Derived() 成立的前提是 Derived 已实现全部纯虚函数
  • 不能对抽象类使用 std::make_unique()std::shared_ptr(new Base)
  • 若用模板工厂(如 create()),模板实参必须是具体类型

例外情况:抽象类的纯虚析构函数可以有实现,且不影响实例化规则

如果只为支持多态删除而声明纯虚析构函数(virtual ~Base() = 0;),**必须提供定义体**,否则链接失败。但这不改变抽象性——该类依然不可实例化。

正确写法:

class Base {
public:
    virtual ~Base() = 0;
};
Base::~Base() {} // 必须定义,哪怕为空

容易踩的坑:

  • 只声明 = 0 而不定义,链接时报 undefined reference to 'Base::~Base()'
  • 误以为加了析构实现就“解除抽象”,其实只要还有别的纯虚函数,仍不能实例化

抽象类的核心约束始终落在“是否所有纯虚函数都被覆盖”上,而不是有没有构造函数、有没有数据成员,或者析构函数怎么写。最常被忽略的是:即使只漏写一个 override,整个继承链就卡在抽象层动不了。

免责声明:转载请注明出处:http://shjed.com/news/758128.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!