c ++成员在父和子构造函数之间更改值

时间:2015-03-10 16:49:08

标签: c++ inheritance vector constructor eigen

我遇到一个错误,其中基类的受保护成员的值在调用父类构造函数和调用子构造函数之间更改值。 代码的精简版如下:

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打破。

在构造过程中是否还有其他隐藏步骤会导致此错误?任何可能导致此类问题的编译器设置?

3 个答案:

答案 0 :(得分:1)

根据C ++中的构造规则,子构造函数将始终打印大小为1.子构造代码在父构造完全完成之前不会执行(更多在{ {3}})。

看起来Child类正在为向量使用垃圾内存地址。

Child.hppParent.cpp是否可能包含Parent.hpp文件的不同版本(您有二进制/标题不匹配)?

答案 1 :(得分:0)

您的构造函数定义错误,您的示例中存在拼写错误,并且您没有正确调用基本构造函数。

如果您对父构造函数定义使用了正确的A::Parent::Parent(...) { }语法,并为子构造函数使用了B::Child::Child(...) : A::Parent(...) { },那么您的示例将进行编译。

See it work in ideone.com

答案 2 :(得分:0)

它仅在Windows上打破,使用与此类似的生产代码,但此测试snippit在Windows和posix上正常工作?

检查Windows框中安装的Eigen库版本。

当你破坏init_Rcam_时,检查std :: vector发生了什么奇怪的事情(因为std :: vector应该有副本,所以应该没问题)

检查退出A :: Parent :: Parent()构造函数时可能损坏内存的无关错误,但是当你提取工作简化代码时这似乎无关紧要。