You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何含虚函数时聚合初始化无法生效?

为结构体引入虚函数后无法使用聚合初始化的解决方法

问题描述

给结构体添加虚函数(或继承含虚函数的结构体)后,无法再使用聚合初始化,报错:

error C2440: 'initializing': cannot convert from 'initializer list' to 'Point_3'

聚合初始化相比手动逐个成员赋值便捷得多:

A.x = 100;
A.y = 100;

示例代码如下:

#include <iostream>

struct Point_1 {
    int x;
    int y;

    void foo() {
        std::cout << "x: " << x << std::endl;
        std::cout << "y: " << y << std::endl;
    }
};

struct Point_2 {
    int x;
    int y;

    virtual void foo() {}
};

struct Point_3 : Point_2 {
    void foo() override {
        std::cout << "x: " << x << std::endl;
        std::cout << "y: " << y << std::endl;
    }
};

int main() {
    Point_1 A = { 100, 100 };
    A.foo();

    Point_3 B = { {200, 200} }; // 报错位置
    B.foo();

    return 0;
}

原因

C++标准明确规定:包含虚函数、虚基类,或继承非聚合类的类/结构体,不属于聚合类型,因此无法使用聚合初始化:

  • Point_1是普通结构体,属于聚合类型,支持聚合初始化;
  • Point_2因包含虚函数,不再是聚合类型;
  • Point_3继承自非聚合类型Point_2,自然也不属于聚合类型,所以原初始化方式会报错。

解决方案

1. 添加构造函数

为基类定义构造函数,派生类可继承该构造函数,用构造函数初始化替代聚合初始化:

struct Point_2 {
    int x;
    int y;

    virtual void foo() {}
    // 添加带参构造函数
    Point_2(int x_val, int y_val) : x(x_val), y(y_val) {}
};

struct Point_3 : Point_2 {
    using Point_2::Point_2; // 继承基类的构造函数
    void foo() override {
        std::cout << "x: " << x << std::endl;
        std::cout << "y: " << y << std::endl;
    }
};

// 初始化方式
Point_3 B(200, 200);

2. C++20及以上使用指定成员初始化

C++20放宽了非聚合类型的初始化规则,支持直接指定成员赋值:

// 仅适用于C++20及更高版本
Point_3 B = { .x = 200, .y = 200 };

3. 手动成员赋值(备选)

如果无法修改结构体定义,只能手动逐个赋值:

Point_3 B;
B.x = 200;
B.y = 200;

内容的提问来源于stack exchange,提问作者machine_1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 22:13:32