简体   繁体   English

在 C++11 中使用(阴影)基类数据成员初始化结构

[英]Initialize struct with (shadowed) base-class data members in C++11

It's possible to add members to a derived struct that shadow same-name members of the base class, whether this is an error or not is addressed by another Q&A .这是可能的成员添加到衍生struct ,所述基类的影子同名成员,这是否是错误或不被寻址的另一个Q&A My question is about initializing hidden inherited members.我的问题是关于初始化隐藏的继承成员。 By-value assignment of derived D to base class B is permitted by the is-a relationship, but it's hard to initialize the inherited member that corresponds to the base class. is-a 关系允许派生D到基类B按值赋值,但很难初始化对应于基类的继承成员。 In the following example, initialization is done with a brace-enclosed initializer list for B but this is not possible for D .在下面的示例中,初始化是使用大括号括起来的B初始化器列表完成的,但这对于D是不可能的。 The only option I found for getting defined D instances was to default-initialize (zero) and assign afterwards:我发现获得定义的D实例的唯一选择是默认初始化(零)并在之后分配:

#include <iostream>
using namespace std;

int main()
{
    struct B { int x; };
    struct D: B { int x; };
    B bas = {1};
    cout << bas.x << endl;
    D der = {};
    der.x = 2;
    bas = der;
    cout << bas.x << endl;
    der.B::x = 3;
    bas = der;
    cout << bas.x << endl;
    static_cast<B&>(der).x = 4;
    bas = der;
    cout << bas.x << endl;
    return 0;
}

output:输出:

1
0
3
4

The following ideas, which I assumed might work, resulted in compiler errors:我认为可能有效的以下想法导致了编译器错误:

    D der = {1, 2};

error: could not convert '{1, 2}' from '<brace-enclosed initializer list>' to 'main()::D'错误:无法将“{1, 2}”从“<括号内的初始化列表>”转换为“main()::D”

    D der = {B::x=1, 2};

error: invalid use of non-static data member 'main()::B::x'错误:非静态数据成员“main()::B::x”的无效使用

error: could not convert '{<expression error>, 2}' from '<brace-enclosed initializer list>' to 'main()::D'错误:无法将 '{<expression error>, 2}' 从 '<brace-enclosed initializer list>' 转换为 'main()::D'

( g++.exe -Weffc++ -pedantic -Wextra -Wall -std=gnu++11 -std=c++11 -fexceptions -g -std=c++11 with gcc 8.1.0) g++.exe -Weffc++ -pedantic -Wextra -Wall -std=gnu++11 -std=c++11 -fexceptions -g -std=c++11 with gcc 8.1.0)

Is there a way for proper initialization in C++11?有没有办法在 C++11 中正确初始化?

Addendum:附录:
When I asked this question, I was so focused on the difficulties to access shadowed members that I totally missed the limited options for aggregate initialization in C++11.当我问这个问题时,我非常关注访问影子成员的困难,以至于我完全错过了 C++11 中聚合初始化的有限选项。 So answers to this question will also apply to derived classes without hidden data members.所以这个问题的答案也适用于没有隐藏数据成员的派生类。

D der = {1, 2} would work in C++17, as D der = {1, 2}将在 C++17 中工作,如

D der = {{42}, 2};

Demo演示

For previous version, you cannot initialize base like that and you need a constructor.对于以前的版本,您不能像这样初始化 base 并且需要一个构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM