重载构造函数中的成员初始化
Member Initialization in overloaded constructor
我有一个基本的语义相关疑问,我无法得到澄清。在陈述问题之前,我会写下最少的代码来解释清楚。
在Constants.hpp
#pragma once
enum class OpenglESVersion{
OES1,
OES2
};
在Cone.hpp中,我有一个枚举成员
OpenglESVersion esVersion;
Cone.cpp 中以枚举作为参数的重载构造函数定义
Cone::Cone(const OpenglESVersion version) : rotationAngle(0), scale(1), esVersion(version) {}
现在在我的 RenderingEngine.cpp 中实例化 Cone 对象时:
Cone cone(OpenglESVersion::OES2);
我收到语法错误:
No type named 'OES2' in 'OpenglESVersion'
现在,如果我将我的对象实例更新为:
Cone cone{OpenglESVersion::OES2};
现在可以了。
我的编译器是 libc++[支持 c++11 的 LLVM c++ 标准库]
,方言是 c++11[-std=c++11]
我正在使用 XCode.
现在我怀疑:
我通过资源来澄清这个概念。过去我在学校使用 pre c++11 版本,遵循 2008 年印刷的 Bjarne 的 C++ 编程书,所以这就是为什么我没有在书中找到这个 "curly" 初始化语法的原因 c++11 出来了稍后。
我尝试了 google,但不确定要搜索什么关键字,但后来最常见的主题名称指向 "list initialization"。几乎所有资源都涵盖了 c++11 中这种新语法的优势,但我从来没有弄清楚为什么普通圆括号被视为语法错误,因为那里有很多资源,示例显示也使用圆括号和大括号组合在解释差异时,他们使用的是原始类型的示例,例如:
int x(4);
int x{4};
所以这又没有为我澄清这个概念。现在我来这里是为了了解或获得一些适当的 link 或解释我的疑问的资源的指导。
- 我的编译器是否生成了圆括号初始化语法
过时了?
- 它没有过时但从未在 c++ 中受支持?
- 我错误地声明和定义了重载的构造函数?
- 是否不支持通过圆括号语法初始化成员?
为什么?
编辑:
对于任何重载版本都会发生这种情况,假设构造函数的 int 参数重载版本。
Cone::Cone(const int fooVariable) : fooMember(fooVariable){}
唯一有效的代码是:
Cone cone{8};
我明白了
Expected parameter declarator, Expected ')'
对于Cone cone(8);
如果出于好奇我在 Cone class 本身的成员函数内部实例化,就像编译器不抛出任何语法或某些错误一样,这种行为不会发生:
void Cone::Test(){
Cone cone(OpenglESVersion::OES2);
}
编辑更新 2:
我想我还有另一个测试用例,它肯定会缩小范围。所以这是模式:
class RenderingEngine
{
private:
Cone cone(OpenglESVersion::OES2);
};
所以我将 Cone 对象声明并实例化为 RenderingEngine class 的成员。那么这可能是导致我的问题的原因吗?因为如果我这样做
Cone cone(OpenglESVersion::OES2);
在 RenderingEngine/Outside class 实现的任何成员函数中然后它就可以工作。所以必须有一些基本规则,我违反了非原始成员变量可以声明和实例化的内容和方式。
C++11 引入了成员初始化。
不支持括号以避免最麻烦的解析,因此您可以使用 {
..}
或 =
语法:
class RenderingEngine
{
private:
Cone cone{OpenglESVersion::OES2};
};
或
class RenderingEngine
{
private:
Cone cone = Cone(OpenglESVersion::OES2); // With =, you can use parent on right side
};
我有一个基本的语义相关疑问,我无法得到澄清。在陈述问题之前,我会写下最少的代码来解释清楚。
在Constants.hpp
#pragma once
enum class OpenglESVersion{
OES1,
OES2
};
在Cone.hpp中,我有一个枚举成员
OpenglESVersion esVersion;
Cone.cpp 中以枚举作为参数的重载构造函数定义
Cone::Cone(const OpenglESVersion version) : rotationAngle(0), scale(1), esVersion(version) {}
现在在我的 RenderingEngine.cpp 中实例化 Cone 对象时:
Cone cone(OpenglESVersion::OES2);
我收到语法错误:
No type named 'OES2' in 'OpenglESVersion'
现在,如果我将我的对象实例更新为:
Cone cone{OpenglESVersion::OES2};
现在可以了。
我的编译器是 libc++[支持 c++11 的 LLVM c++ 标准库] ,方言是 c++11[-std=c++11] 我正在使用 XCode.
现在我怀疑: 我通过资源来澄清这个概念。过去我在学校使用 pre c++11 版本,遵循 2008 年印刷的 Bjarne 的 C++ 编程书,所以这就是为什么我没有在书中找到这个 "curly" 初始化语法的原因 c++11 出来了稍后。
我尝试了 google,但不确定要搜索什么关键字,但后来最常见的主题名称指向 "list initialization"。几乎所有资源都涵盖了 c++11 中这种新语法的优势,但我从来没有弄清楚为什么普通圆括号被视为语法错误,因为那里有很多资源,示例显示也使用圆括号和大括号组合在解释差异时,他们使用的是原始类型的示例,例如:
int x(4);
int x{4};
所以这又没有为我澄清这个概念。现在我来这里是为了了解或获得一些适当的 link 或解释我的疑问的资源的指导。
- 我的编译器是否生成了圆括号初始化语法 过时了?
- 它没有过时但从未在 c++ 中受支持?
- 我错误地声明和定义了重载的构造函数?
- 是否不支持通过圆括号语法初始化成员? 为什么?
编辑: 对于任何重载版本都会发生这种情况,假设构造函数的 int 参数重载版本。
Cone::Cone(const int fooVariable) : fooMember(fooVariable){}
唯一有效的代码是:
Cone cone{8};
我明白了
Expected parameter declarator, Expected ')'
对于Cone cone(8);
如果出于好奇我在 Cone class 本身的成员函数内部实例化,就像编译器不抛出任何语法或某些错误一样,这种行为不会发生:
void Cone::Test(){
Cone cone(OpenglESVersion::OES2);
}
编辑更新 2: 我想我还有另一个测试用例,它肯定会缩小范围。所以这是模式:
class RenderingEngine
{
private:
Cone cone(OpenglESVersion::OES2);
};
所以我将 Cone 对象声明并实例化为 RenderingEngine class 的成员。那么这可能是导致我的问题的原因吗?因为如果我这样做
Cone cone(OpenglESVersion::OES2);
在 RenderingEngine/Outside class 实现的任何成员函数中然后它就可以工作。所以必须有一些基本规则,我违反了非原始成员变量可以声明和实例化的内容和方式。
C++11 引入了成员初始化。
不支持括号以避免最麻烦的解析,因此您可以使用 {
..}
或 =
语法:
class RenderingEngine
{
private:
Cone cone{OpenglESVersion::OES2};
};
或
class RenderingEngine
{
private:
Cone cone = Cone(OpenglESVersion::OES2); // With =, you can use parent on right side
};