c ++成员在父子构造函数之间更改值
c++ members changing value between parent and child constructor
我遇到一个错误,其中基 class 的受保护成员的值在调用父 class 构造函数和调用子构造函数之间发生变化。
代码的精简版本如下:
Namespace A
{
class Parent
{
public:
Parent (int a, int b, int c, int d);
protected:
std::vector<Eigen::Matrix<float, 3, 3, Eigen::RowMajor>> rmats_;
}
}
A::Parent::Parent (int a, int b, int c, int d) {
rmats_.reserve(3000);
rmats_.clear ();
Eigen::Matrix<float, 3, 3, Eigen::RowMajor> init_Rcam_ = Eigen::Matrix3f::Identity ();
rmats_.push_back(init_Rcam_);
std::cout << "size of rmats is " << rmats_.size() << std::endl;
}
Namespace B
{
class Child : public Parent
{
public:
Child(int a, int b, int c, int d);
}
}
B::Child::Child : A::Parent::Parent(a,b,c,d)
{
std::cout << "size of rmats in the child is " << rmats_.size() << std::endl;
}
创建子对象时,父构造函数中的大小报告预期大小为 1,但是子对象中的输出报告向量大小现在为 127101589483567331。还有其他几个向量真实代码中的类似对象都报告不正确的向量大小,包括另一个大小为 1 的向量更改为大小 0 和一个大小为 3 的向量更改为大小 668637816。
我已经尝试使用整数向量的更简单版本的代码并获得了预期的结果但是完整的代码在两个 print cout 语句之间没有做任何额外的事情表明向量的大小在父构造函数和子构造函数。此外,代码似乎在 Linux 下使用 gcc 正常运行,但在 windows 下使用 visual studio.
中断
在构建过程中是否有任何额外的隐藏步骤会导致此错误?是否有可能导致此类问题的编译器设置?
你的构造函数定义错误,你的例子中有错别字,你没有正确调用基本构造函数。
如果您对父构造函数定义使用正确的 A::Parent::Parent(...) { }
语法并且对子构造函数使用 B::Child::Child(...) : A::Parent(...) { }
语法,则您的示例可以编译。
根据 C++ 中的构造规则,child 构造函数将始终打印大小为 1。child 的构造代码直到 parent 才会执行的构造函数已完全完成(更多内容在 C++: Construction and initialization order guarantees)。
看起来 Child class 正在为向量使用垃圾内存地址。
Child.hpp
和 Parent.cpp
是否可能包括不同版本的 Parent.hpp
文件(您有 binary/header 不匹配)?
它仅在 windows 上中断,使用与此类似的生产代码,但此测试片段在 windows 和 posix 上正常工作?
检查 windows 盒子上安装的 Eigen 库版本。
当你破坏 init_Rcam_ 时检查 std::vector 是否有任何奇怪的事情发生(这应该没问题,因为 std::vector 应该有一个副本)
检查退出 A::Parent::Parent() 构造函数时可能破坏内存的不相关错误,但在您提取工作简化代码时似乎无关紧要。
我遇到一个错误,其中基 class 的受保护成员的值在调用父 class 构造函数和调用子构造函数之间发生变化。 代码的精简版本如下:
Namespace A
{
class Parent
{
public:
Parent (int a, int b, int c, int d);
protected:
std::vector<Eigen::Matrix<float, 3, 3, Eigen::RowMajor>> rmats_;
}
}
A::Parent::Parent (int a, int b, int c, int d) {
rmats_.reserve(3000);
rmats_.clear ();
Eigen::Matrix<float, 3, 3, Eigen::RowMajor> init_Rcam_ = Eigen::Matrix3f::Identity ();
rmats_.push_back(init_Rcam_);
std::cout << "size of rmats is " << rmats_.size() << std::endl;
}
Namespace B
{
class Child : public Parent
{
public:
Child(int a, int b, int c, int d);
}
}
B::Child::Child : A::Parent::Parent(a,b,c,d)
{
std::cout << "size of rmats in the child is " << rmats_.size() << std::endl;
}
创建子对象时,父构造函数中的大小报告预期大小为 1,但是子对象中的输出报告向量大小现在为 127101589483567331。还有其他几个向量真实代码中的类似对象都报告不正确的向量大小,包括另一个大小为 1 的向量更改为大小 0 和一个大小为 3 的向量更改为大小 668637816。
我已经尝试使用整数向量的更简单版本的代码并获得了预期的结果但是完整的代码在两个 print cout 语句之间没有做任何额外的事情表明向量的大小在父构造函数和子构造函数。此外,代码似乎在 Linux 下使用 gcc 正常运行,但在 windows 下使用 visual studio.
中断在构建过程中是否有任何额外的隐藏步骤会导致此错误?是否有可能导致此类问题的编译器设置?
你的构造函数定义错误,你的例子中有错别字,你没有正确调用基本构造函数。
如果您对父构造函数定义使用正确的 A::Parent::Parent(...) { }
语法并且对子构造函数使用 B::Child::Child(...) : A::Parent(...) { }
语法,则您的示例可以编译。
根据 C++ 中的构造规则,child 构造函数将始终打印大小为 1。child 的构造代码直到 parent 才会执行的构造函数已完全完成(更多内容在 C++: Construction and initialization order guarantees)。
看起来 Child class 正在为向量使用垃圾内存地址。
Child.hpp
和 Parent.cpp
是否可能包括不同版本的 Parent.hpp
文件(您有 binary/header 不匹配)?
它仅在 windows 上中断,使用与此类似的生产代码,但此测试片段在 windows 和 posix 上正常工作?
检查 windows 盒子上安装的 Eigen 库版本。
当你破坏 init_Rcam_ 时检查 std::vector 是否有任何奇怪的事情发生(这应该没问题,因为 std::vector 应该有一个副本)
检查退出 A::Parent::Parent() 构造函数时可能破坏内存的不相关错误,但在您提取工作简化代码时似乎无关紧要。