构造函数销毁成员变量
Constructor destroys member variables
为什么第二次调用构造函数时会删除初始化的成员变量?
例:
class MyClass {
private:
unsigned myValue;
public:
MyClass(void)
{
this->myValue = 1337;
fprintf(stderr, "myValue: %dn", this->myValue);
}
MyClass(int myFirstValue)
{
fprintf(stderr, "myValue: %dn", this->myValue);
}
};
int main()
{
/* Constructor is called */
MyClass myInstance;
/* Call other constructor ; myInstance->myValue is now trashed */
myInstance = 100;
return 0;
}
输出:
myValue: 1337
myValue: 1606416392
预期输出:
myValue: 1337
myValue: 1337
有没有办法保留初始化的成员变量?
当你这样做时
myInstance = 100;
使用构造函数MyClass(int)
在 RHS 上构造临时MyClass
。然后使用临时值为 LHS 分配值。
该构造函数不初始化成员变量。读取未初始化的成员会导致未定义的行为,在您的情况下,这似乎会导致打印垃圾值。
因此,您需要初始化它,假设您要将成员初始化为构造函数中传递的值:
MyClass(int myFirstValue) : myValue(myFirstValue)
{
// as before
}
编辑,因为您希望成员的值1337
,您需要
MyClass(int myFirstValue) : myValue(1337) { .... }
myInstance = 100;
是对函数MyClass& MyClass::operator=( MyClass const &other)
的调用
但由于您没有实现它,因此调用了默认赋值运算符。如您所见,此函数将引用MyClass
参数。这意味着必须将整数文字1 100
转换为 MyClass
。C++实现可以自由地执行这样的隐藏的、用户定义的转换。在这种情况下,它做到了。由于您不初始化整数成员 MyClass(int myFirstValue)
因此将进行默认初始化2。对于int
变量,这意味着没有初始化和不确定的值。然后,尝试读取此未定义的值并将其分配给原始对象。这会导致未定义的行为,因此从现在开始,程序的行为是未定义的,非确定性的。
您可以将构造函数限制为仅使用 word explicit
显式调用,并解决此问题,初始化整数成员:
MyClass( int myFirstValue) : myValue( myFirstValue)
{
//....
}
C++ 标准 n3337 § 12.3 转换
1) 类对象的类型转换可以由构造函数指定 以及通过转换功能。这些转换称为用户定义 转换,用于隐式类型转换(条款 4),用于 初始化 (8.5) 和显式类型转换 (5.4、5.2.9)。
2) 用户定义的转换仅在其所在位置应用 明确(10.2、12.3.2)。转换遵守访问控制规则 (第11条)。在解决歧义后应用访问控制 (3.4).
3) [ 注:有关在 函数调用以及下面的示例。— 尾注 ]
4) 最多一个用户定义的转换(构造函数或转换) 函数)隐式应用于单个值。
1 C++ 标准 n3337 § 2.14.2 文字 1) 整数文字是没有句点或指数部分的数字序列。整数文本可能具有指定其基数的前缀和指定其类型的后缀。序列的词法上的第一个数字数字是最重要的。十进制整数文本(以十为基数)以 0 以外的数字开头,并且由一系列十进制数字组成。八进制整数文本(以 8 为基数)以数字 0 开头,并且由一系列八进制数字组成。22 十六进制整数文本(以十六进制为基数)以 0x 或 0X 开头,并且由一系列十六进制数字组成,其中包括十进制数字和字母 A 到 F以及 A 到 F,十进制值为 10 到 15。[例:数字十二可以写成12,014,或0XC。— 结束示例 ]
2 C++ 标准 n3337 § 8.5 初始值设定项 6) 默认初始化类型 T 的对象意味着:— 如果 T 是(可能符合 cv 条件的)类类型(条款 9),则调用 T 的默认构造函数(和如果 T 没有可访问的默认构造函数,则初始化格式不正确);— 如果 T 是数组类型,则每个元素都是默认初始化的;— 否则,不执行初始化。如果程序调用 const 限定类型 T 的对象的默认初始化,则 T 应为类使用用户提供的默认构造函数键入。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- C++预处理会生成变量成员、资源库和映射
- 局部堆栈变量成员的返回值优化
- Google Mock:在目标类的构造函数中实例化的模拟私有变量成员
- 使用指向结构变量成员的指针访问该结构的成员的地址
- 如果派生类仅包含自动变量成员,是否有必要具有虚拟驱动器
- 线程安全性和静态变量/成员功能
- "static const char array"可以在 C 语言上包含变量成员吗
- 仅用于内部目的的类的所有变量/成员的技术术语是什么
- 如何强制转换变量成员以将其作为函数的引用参数传递
- 类中未声明变量成员函数
- 在 main 中初始化类的 "static const" 类型变量成员的更好方法
- c++模板类静态const变量成员作为映射键给出未定义引用
- 在类中初始化结构变量成员会导致分割错误
- 在c++中建模变量成员类型
- 模板私有静态变量成员的未定义符号
- 不能访问公共静态变量成员
- 常量变量成员在C++有什么用?
- g++ 4.8.2坚持简单变量成员是数组