C++ 在初始值设定项列表中使用此选项
假设我有一个类C++ 在初始值设定项列表中使用此选项,c++,this,language-lawyer,initializer-list,C++,This,Language Lawyer,Initializer List,假设我有一个类Baz,它按顺序继承自类Foo和Bar。类Bar的构造函数获取指向Foo对象的指针。我想做的是将this作为Foo对象传递给Bar构造函数: Baz () : Foo(), Bar(this) {} 一个有效的例子: #include <iostream> class Bar; class Foo { public: virtual ~Foo() {} virtual void parse_bar (Bar&) const = 0; }; c
Baz
,它按顺序继承自类Foo
和Bar
。类Bar
的构造函数获取指向Foo
对象的指针。我想做的是将this
作为Foo
对象传递给Bar
构造函数:
Baz () : Foo(), Bar(this) {}
一个有效的例子:
#include <iostream>
class Bar;
class Foo {
public:
virtual ~Foo() {}
virtual void parse_bar (Bar&) const = 0;
};
class Bar {
private:
const Foo * parser;
public:
Bar (const Foo * parser_in) : parser(parser_in) {}
virtual ~Bar() {}
void parse_self () { parser->parse_bar (*this); }
};
class Baz : public Foo, public Bar {
public:
Baz () : Foo(), Bar(this) {}
virtual void parse_bar (Bar &) const { std::cout << "Hello World\n"; }
};
int main () {
Baz baz;
baz.parse_self();
}
#包括
分类栏;
福班{
公众:
虚拟~Foo(){}
虚空解析_bar(bar&)const=0;
};
分类栏{
私人:
constfoo*解析器;
公众:
Bar(const Foo*parser_in):parser(parser_in){
虚拟~Bar(){}
void parse_self(){parser->parse_bar(*this);}
};
Baz类:公共餐厅、公共酒吧{
公众:
Baz():Foo(),Bar(this){}
虚虚空PARSEBAR(bar & const){STD::CUT它是好的。C++标准实际上澄清了使用< <代码> < /COD>指针在初始化列表中:
12.6.2初始化基和成员[class.base.init]
段落7:mem初始值设定项的表达式列表中的名称在指定mem初始值设定项的构造函数范围内进行评估。[示例:
初始化X::r
要参考X::a
,请使用
构造函数参数i
的值,用
构造函数参数i
的值,并且使用
X::i
的值;每次类的对象X
已创建。][注意:因为mem初始值设定项
是在
构造函数的范围,此
指针可用于
mem初始值设定项的表达式列表
,用于引用正在创建的对象
已初始化。]
Baz
的初始值设定项中的此
指针的类型实际上是Baz
类型。当然,您必须注意的是,并非所有成员都已初始化。许多(如果不是全部的话)编译器将其设置为最高警告级别(无论如何,您确实应该这样做)将警告您将此
指针传递到基类
但是,看起来您正在使它变得更加复杂。为什么不将虚拟函数parse_bar()
放在bar
类中,而忘记Foo
类呢
#include <iostream>
class Bar
{
public:
Bar() {}
virtual ~Bar() {}
void parse_self () { parse_bar(); }
private: // Template method pattern
virtual void parse_bar() const = 0;
};
class Baz : public Bar
{
public:
Baz () {}
private: // Yes, this does override the private `parse_bar()` member!
virtual void parse_bar() const { std::cout << "Hello World\n"; }
};
int main ()
{
Baz baz;
baz.parse_self();
}
#包括
分类栏
{
公众:
Bar(){}
虚拟~Bar(){}
void parse_self(){parse_bar();}
私有模板方法模式
虚空解析_bar()常量=0;
};
Baz类:公共酒吧
{
公众:
Baz(){}
private://是的,这会覆盖private`parse_bar()`成员!
virtualvoid parse_bar()const{std::cout在这种情况下有两点需要注意
首先,在构造函数初始值设定项列表中,此
指针指的是未构造(或未完全构造)的对象。可以访问此类指针,但它所指的对象只能以有限的方式使用。请参见语言规范中的12.7
其次,在您的具体示例中,您实际正在做的是在尝试任何访问之前将此
指针转换为Foo*
类型。这是完全安全的,因为此时Foo
子对象已完全构建。(我假设,接下来的任何访问(如果有的话)都将仅限于完全构造的Foo
子对象)
唯一值得关注的是,在这种情况下,将this
转换为Foo*
类型是否合法,即转换过程本身是否应该成功。答案是:是的,在普通(非虚拟)继承的情况下,这种转换是完全合法和安全的(同样,在12.7中明确允许)@GManNickG Dont!这些评论可能对你的工作有用newbies@Evgeni:对不起。:)新手!关于类继承的问题?->。谢谢,AndreyT。呼。这将帮助我摆脱僵局。+1,很好的答案,电子版。选择哪个答案很难。关于我发布的代码和你建议的修复:我的代码是为了说明用法而设计的;一个MWE。它看起来与我必须处理的代码完全不同。
#include <iostream>
class Bar
{
public:
Bar() {}
virtual ~Bar() {}
void parse_self () { parse_bar(); }
private: // Template method pattern
virtual void parse_bar() const = 0;
};
class Baz : public Bar
{
public:
Baz () {}
private: // Yes, this does override the private `parse_bar()` member!
virtual void parse_bar() const { std::cout << "Hello World\n"; }
};
int main ()
{
Baz baz;
baz.parse_self();
}