不要注意实际代码,只需阅读问题。 我有一个函数,它采用多项式类型的2个参数:
FiniteFieldElement(int l, Polynomial p, Polynomial irr)
{
this->l = l;
this->p = p;
this->irr = irr;
}
我的理解是,当p和irr被传递时,将调用Polynomial的复制构造函数。
复制构造函数正常工作,因为我可以通过最后的断点进行验证。
Polynomial(const Polynomial& p)
{
degree = p.degree;
modulo = p.modulo;
if (polynomial != p.polynomial)
{
polynomial = new int[degree + 1];
for (int i = 0; i <= degree; i++)
{
polynomial[i] = p.polynomial[i];
}
}
}
但为什么我得到实际参数p和irr的错误(未初始化)值。复制构造函数的结果和实际参数之间可能会有什么结果?如果我将参数更改为参考参数,它可以正常工作。 (注意:多项式没有析构函数,如果有帮助的话)。
编辑:如果我使用复制构造函数Polynomial p1(p2)
声明多项式,则p1会被正确初始化。在FiniteFieldElement类中,我得到了错误的多项式参数。我完全难过了。
答案 0 :(得分:3)
我的理解是,当p和irr被传递时,将调用Polynomial的复制构造函数。
这只是部分正确。由于Polinomials
是按值传递的,因此可能会复制(但复制省略可能意味着根本没有复制),但在FiniteFieldElement(int l, Polynomial p, Polynomial irr)
内,Polynomial
的复制赋值运算符将是假设this->p
和this->irr
属于Polynomial
类型,则调用此方法。所以你的班级字段是作业的结果,而不是副本。
因此,您应该查看复制赋值运算符的实现。
答案 1 :(得分:1)
你实际初始化多项式吗?
执行new int[degree_ + 1];
不会构造初始化的数组,其值是垃圾。
编辑:除非您有另一个很好的理由需要int*
,否则最好使用std::vector
作为多项式系数容器。它将简化对象构造,破坏和分配。
这很有效(这意味着问题出在您未向我们展示的代码部分:类定义和赋值运算符)
class Polynomial
{
public:
Polynomial();
Polynomial( const Polynomial& p );
template <int N> Polynomial(int (&Poly)[N] );
Polynomial& operator=( const Polynomial& Rhs);
void Print();
~Polynomial();
private:
int* poly_;
int degree_;
};
class FiniteFieldElement
{
public:
FiniteFieldElement( Polynomial P );
void Print();
private:
Polynomial p_;
};
和实施:
Polynomial::Polynomial()
{
degree_ = 0;
poly_ = new int[degree_ + 1];
poly_[0] = 1;
}
// excessive, you don't really need this
template <int N> Polynomial::Polynomial(int (&Poly)[N] )
{
degree_ = N - 1;
poly_ = new int[degree_ + 1];
for (int i = 0; i <= degree_; i++)
{
poly_[i] = Poly[i];
}
}
Polynomial& Polynomial::operator=( const Polynomial& Rhs)
{
if ( this != &Rhs )
{
degree_= Rhs.degree_;
delete[] poly_;
poly_ = new int[degree_ + 1];
for (int i = 0; i <= degree_; i++)
{
poly_[i] = Rhs.poly_[i];
}
}
return *this;
}
void Polynomial::Print()
{
std::cout<< "Degree = " << degree_ << "\n Polynomial = ";
for (int i = 0; i <= degree_; i++)
{
std::cout<< poly_[i] << " ";
}
std::cout<<"\n";
}
Polynomial::~Polynomial()
{
delete[] poly_;
}
Polynomial::Polynomial(const Polynomial& p)
{
degree_ = p.degree_;
poly_ = new int[degree_ + 1];
for (int i = 0; i <= degree_; i++)
{
poly_[i] = p.poly_[i];
}
}
和
FiniteFieldElement::FiniteFieldElement( Polynomial P )
{
p_ = P;
}
void FiniteFieldElement::Print()
{
p_.Print();
}
主要是:
int main(int argc, _TCHAR* argv[])
{
int myPoly[] = { 1, 2, 3 };
Polynomial foo(myPoly);
FiniteFieldElement bar( foo );
std::cout<< "Foo:\n";
foo.Print();
std::cout<< "Bar:\n";
bar.Print();
return 0;
}
如果它适用于您的计算机,请在代码和行为中查看它与您的实现的不同之处。
答案 2 :(得分:0)
感谢大家,事实证明Eclipse CDT调试器给了我错误的值。 Visual Studio中的相同断点(或只是打印值[见下面的模数])给出了正确的答案。也许我没有正确使用它,但是当您在调试器中输入监视表达式时,您希望得到正确的值。