草庐IT

对于指向同一基类的其他类的指针,C++11 非静态数据成员统一初始化失败

coder 2024-02-10 原文

我是一名 C 老手,他试图通过将我的旧状态机框架从 C 移植到 C++11 来学习 C++11。我的想法是为状态机本身创建一个类,然后为其中的状态创建一个嵌套类。状态可以是分层的,即超状态和子状态。框架需要了解状态的超状态,为此我在嵌套状态类中有一个指针 (state *superstate)。

我的问题是我打算通过直接在机器类中使用构造函数来设置超状态指针,这在 C++11 中应该是可能的,通过使用统一初始化进行非静态数据成员初始化。但由于某些原因,当设置为另一种类型的状态/类时,它无法编译 (substateB3{superstateA})。但如果我稍后为此目的使用特定函数 (set_superstate) 设置它,它就可以正常工作,该函数具有与构造函数相同的参数!有趣的是,如果我将超状态设置为相同类型的状态/类 (substateB2{substateB1}),构造函数就会被接受。

我正在使用 gcc 4.7.0(以获得对非静态数据成员初始值设定项的支持),这是我的代码:

// My state-machine framework (simplified)
struct machine {
  struct state {
    state()                  : superstate(nullptr) { }     // No superstate => toplevel state!
    state(state &superstate) : superstate(&superstate) { }
    state *superstate;
    void set_superstate(state &superstate) { this->superstate = &superstate; } // Non-ctor way to set superstate
  };
};

// An example of a specific state-machine using my framework
struct Machine : machine {
  struct SuperstateA : state {
  } superstateA;

  struct SubstateB : state {
  } substateB1,              // Compiles OK; gets its superstate set in Machine's ctor below
    substateB2{substateB1},  // Compiles OK; but not correct superstate
    substateB3{superstateA}; // gcc 4.7.0 error: could not convert ‘{((Machine*)this)->Machine::superstateA}’ from ‘<brace-enclosed initializer list>’ to ‘Machine::SubstateB’

  Machine()  { substateB1.set_superstate(superstateA); } // Compiles OK;
} myMachine;

非常感谢任何提示或指导,谢谢! :)

最佳答案

剥离一层继承:

struct m {
    struct state { state *s;
        state() : s(0) {};
        state(state &s) : s(&s) {}
        set(state &s) { this->s = &s; }
    };

    struct s1 : state {} A;   // calls s1(), the default constructor
    struct s2 : state {}    B     // calls s2(), ditto
    ,                       C{B}  // calls s2(const s2&), the default copy constructor
    ,                       D{A}; // calls s2(const s1&)

    m() { B.set(A); } // The m() body runs after all the members are constructed.
} M;

你得到构造错误是因为你的子状态没有声明构造函数所以它们得到了编译器提供的默认值,并且没有来自兄弟类或基类引用(编译器不提供 s2(s1&)s2(state&)).

C 的超状态是错误的,因为 C{B} 调用了默认的复制构造函数 s2(s2&),它运行在 m() 的主体之前。

这是你想要的:

struct m {
    struct state { state *s; state() : s(0) {} state(state &s) : s(&s) {} };
    struct s1 : state {} A; // default-constructs, fine
    struct s2 : state {
        s2(state &s) : state(s) {}
        s2(s2&s)     : state(s) {}
    }            B     // default-constructs
    ,            C{B}  // calls s2(s2&), invokes state(state&)
    ,            D{A}; // calls s2(state&)
    ;
    m() : B(A) {};
} M;

当 M 的构造函数运行时,首先是它的基类(没有基类),然后是使用指定的初始化按声明顺序构造它的成员。只有一个:B(A),所以其余的都是默认值。构造完所有基类和成员后,对象构造函数的主体就会运行。

关于对于指向同一基类的其他类的指针,C++11 非静态数据成员统一初始化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10677237/

有关对于指向同一基类的其他类的指针,C++11 非静态数据成员统一初始化失败的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  6. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  7. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  8. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  9. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  10. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

随机推荐