当我在operator *函数中返回对象temp时,它不会被复制到main中的p3。
operator *函数中的cout语句返回正确的值,但main中的p3只有垃圾。
此外,我在main的return 0语句中获得_block_type_is_valid(phead-> nblockuse)。
这是代码。
#pragma once
#include<iostream>
using namespace std;
class Polynomial
{
private:
int *coefficients;
int length;
public:
inline int getLength() const {return length;}
Polynomial(int length);
Polynomial(const Polynomial &p);
Polynomial():coefficients(nullptr){}
~Polynomial(void);
extern friend Polynomial operator*(const Polynomial &p1,const Polynomial &p2);
inline int operator[](int n) const { return coefficients[n];}
inline int& operator[](int n) { return coefficients[n];}
Polynomial& operator=(Polynomial &p);
friend void swap(Polynomial& first, Polynomial& second);
void resize(int x);
friend istream& operator>>(istream &is, Polynomial &p);
friend ostream& operator<<(ostream &os, Polynomial &p);
};
这是polynomial.cpp
#include "Polynomial.h"
Polynomial::Polynomial(int length){
this->length = length;
coefficients = new int[length];
for(int i = 0; i < length; i++){
coefficients[i] = 0;
}
}
Polynomial::~Polynomial(void){
cout<<"Deleting: "<<coefficients;
delete[] coefficients;
}
/*
Polynomial Polynomial::operator*(Polynomial p){
Polynomial temp(length + p.getLength());
for(int i = 0; i < length; i++){
for(int j = 0; j < length; j++){
temp[i+j] += coefficients[i] * p[j];
}
}
cout<<temp;
return temp;
}*/
Polynomial operator*(const Polynomial &p1,const Polynomial &p2){
Polynomial temp(p1.getLength() + p2.getLength());
for(int i = 0; i < p1.getLength(); i++){
for(int j = 0; j < p2.getLength(); j++){
temp[i+j] += p1[i] * p2[j];
}
}
cout<<temp;
return temp;
}
void Polynomial::resize(int x){
delete[] coefficients;
coefficients = new int[x];
}
void swap(Polynomial& first,Polynomial& second){
int tempLength = first.getLength();
int *temp = new int[tempLength];
for(int i = 0; i < first.getLength(); i++)
temp[i] = first[i];
first.resize(second.getLength());
for(int i = 0; i < first.getLength(); i++)
first[i] = second[i];
second.resize(tempLength);
for(int i = 0; i < first.getLength(); i++)
second[i] = temp[i];
delete[]temp;
}
Polynomial& Polynomial::operator=(Polynomial &p){
swap(*this,p);
return *this;
}
Polynomial::Polynomial(const Polynomial &p){
//if(coefficients) delete [] coefficients;
coefficients = new int[p.getLength()];
for(int i = 0; i < p.getLength(); i++)
coefficients[i] = p[i];
}
istream& operator>>(istream &is,Polynomial &p){
cout<<"Enter length: ";
is>>p.length;
p.coefficients = new int[p.length];
for(int i = 0; i < p.length; i ++)
is>>p.coefficients[i];
return is;
}
ostream& operator<<(ostream &os,Polynomial &p){
for(int i = 0; i < p.length; i ++)
if(p.coefficients[i])
os<<p.coefficients[i]<<"x^"<<i<<" ";
return os;
}
这是主要的
#include"Polynomial.h"
#include<iostream>
#include<string>
using namespace std;
int main(){
Polynomial p1,p2,p3;
cin>>p1>>p2;
p3 = (p1 * p2);
cout<<p3[0]<<p3[1]<<"here";
cout<<p3;
return 0;
}
编辑:这是最终更正的代码。我需要做的就是在所有构造函数中初始化带有null和length的指针。
#include "Polynomial.h"
Polynomial::Polynomial():
coefficients(nullptr),length(0){}
Polynomial::Polynomial(int length):coefficients(nullptr),length(length){
coefficients = new int[length];
for(int i = 0; i < length; i++){
coefficients[i] = 0;
}
}
Polynomial::~Polynomial(void){
if(coefficients) delete[]coefficients;
}
Polynomial& Polynomial::operator=(const Polynomial &p){
if(coefficients)
delete[]coefficients;
length = p.getLength();
coefficients = new int[length];
for(int i = 0; i < length; i++)
coefficients[i] = p[i];
return *this;
}
Polynomial::Polynomial(const Polynomial &p):
coefficients(nullptr),length(0)
{
length = p.getLength();
coefficients = new int[length];
for(int i = 0; i < length; i++)
coefficients[i] = p[i];
}
Polynomial operator*(const Polynomial &p1,const Polynomial &p2){
Polynomial temp(p1.getLength() + p2.getLength());
for(int i = 0; i < p1.getLength(); i++)
for(int j = 0; j < p2.getLength(); j++)
temp[i+j] += p1[i] * p2[j];
return temp;
}
istream& operator>>(istream &is,Polynomial &p){
cout<<"Enter length: ";
is>>p.length;
p.coefficients = new int[p.length];
for(int i = 0; i < p.length; i ++)
is>>p.coefficients[i];
return is;
}
ostream& operator<<(ostream &os,Polynomial &p){
for(int i = 0; i < p.length; i ++)
if(p.coefficients[i])
os<<p.coefficients[i]<<"x^"<<i<<" ";
return os;
}
答案 0 :(得分:2)
如果使用正确的标志调用编译器,则此代码不能编译。 没有适用于默认标志的C ++编译器!
例如,让我们采用像这样调用的Visual C ++ 2013,带有一些非默认标志:
cl /nologo /EHsc /Za /W4 stackoverflow.cpp
结果是正确的编译器错误:
stackoverflow.cpp(78) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Polynomial' (or there is no acceptable conversion)
stackoverflow.cpp(19): could be 'void Polynomial::operator =(Polynomial &)'
while trying to match the argument list '(Polynomial, Polynomial)'
现在让我们看看如果我们删除/Za
标志会发生什么情况,这会禁用Microsoft扩展程序:
cl /nologo /EHsc /W4 stackoverflow.cpp
错误消失了。但是,会出现警告:
warning C4239: nonstandard extension used : 'argument' : conversion from 'Polynomial' to 'Polynomial &'
A non-const reference may only be bound to an lvalue; assigment operator takes a reference to non-const
最后,让我们看看如果我们删除警告级别标志/W4
,编译器会做什么:
cl /nologo /EHsc stackoverflow.cpp
没有错误,没有警告。这是坏。 p3 = (p1 * p2);
不是标准的C ++。即使您可以使Visual C ++编译代码,也不会有任何好处。
赋值运算符的正确签名是:
Polynomial& Polynomial::operator=(Polynomial const& p);
但是,代码的最大问题是使用new[]
和delete[]
。你当然有某个内存泄漏(构造和赋值都分配,但只有析构函数删除),更糟糕的是,你多次删除相同的数组。
将以下输出添加到析构函数中:
Polynomial::~Polynomial(void){
std::cout << "coefficients address destructor: " << coefficients << "\n";
delete[] coefficients;
}
如果你现在运行它,你会看到类似的东西:
Enter length: 2
100
200
Enter length: 3
100
200
300
10000x^0 40000x^1 40000x^2 coefficients address destructor: 00463BF8
coefficients address destructor: 00463BF8
1040000herecoefficients address destructor: 00463BF8
三次00463BF8
!这是未定义的行为,可能导致您的程序中发生所有可以想象的事情。
但这怎么可能?
答案是您的operator*
返回Polynomial
对象的浅表副本。内部指针被复制,最后有两个指向同一分配内存的指针。
您需要复制构造函数。你必须尊重所谓的三规则:如果你需要实现一个的复制构造函数,复制赋值运算符和析构函数,那么你需要实现它们的所有
然而,不是采取所有麻烦并手动实现动态分配及其无数陷阱,请自己帮忙并使用std::vector
而不是指针和长度变量:
class Polynomial
{
private:
std::vector<int> coefficients;
// ...
};
您的下标运算符也需要修改。实际上,您需要其中两个,一个用于const访问,另一个用于非const访问:
inline int operator[] (int n) const { return coefficients[n];}
inline int& operator[] (int n) { return coefficients[n];}
请参阅why do subscript operators C++ often comes in pair?
最后,我认为你误解了extern
。您不需要它来使用friend
功能。只需从代码中删除它;否则GCC甚至不会编译它。
以下是一个包含最重要修复程序的完整示例:
#include <iostream>
#include <vector>
using namespace std;
class Polynomial
{
private:
std::vector<int> coefficients;
public:
inline int getLength() const {return coefficients.size();}
Polynomial(int length);
Polynomial(){}
Polynomial operator*(Polynomial &p);
inline int operator[] (int n) const { return coefficients[n];}
inline int& operator[] (int n) { return coefficients[n];}
friend istream& operator>>(istream &is, Polynomial &p);
friend ostream& operator<<(ostream &os, Polynomial &p);
};
Polynomial::Polynomial(int length) :
coefficients(length)
{
for(int i = 0; i < length; i++){
coefficients[i] = 0;
}
}
Polynomial Polynomial::operator*(Polynomial &p){
Polynomial temp(coefficients.size() + p.getLength());
for(int i = 0; i < coefficients.size(); i++){
for(int j = 0; j < coefficients.size(); j++){
temp[i+j] += coefficients[i] * p[j];
}
}
cout<<temp;
return temp;
}
istream& operator>>(istream &is,Polynomial &p){
cout<<"Enter length: ";
int length;
is>>length;
p.coefficients.clear();
p.coefficients.resize(length);
for(int i = 0; i < length; i ++)
is>>p.coefficients[i];
return is;
}
ostream& operator<<(ostream &os,Polynomial &p){
for(int i = 0; i < p.coefficients.size(); i ++)
if(p.coefficients[i])
os<<p.coefficients[i]<<"x^"<<i<<" ";
return os;
}
int main(){
Polynomial p1,p2,p3;
cin>>p1>>p2;
p3 = (p1 * p2);
cout<<p3[0]<<p3[1]<<"here";
cout<<p3;
return 0;
}
您不再需要自编写的复制构造函数,复制赋值运算符或析构函数,因为std::vector
知道如何以安全的方式复制,分配和破坏自身,而不会出现低级内存问题
未来改进的进一步示例:
std::cin
实际收到的有效整数。operator*
实施operator*=
。operator*
获得const
参考。using namespace
全局范围。通常,请阅读const
以及有关运算符重载的最佳做法。
答案 1 :(得分:1)
假设它编译。</ em>
你没有复制构造函数,这不是一个好主意。如果实现析构函数,则可能需要assign-copy-swap-move函数。 What is The Rule of Three?(和一半)
此外,最好使用std::vector
而不是动态分配,因为它会自动实现这些行为,编译器生成的构造函数就足够了。
在你的情况下,返回创建一个浅拷贝(自动生成的copy-cstr),但是在函数返回之后,原始文件被破坏 - 它已经分配了浅拷贝所引用的内存 - 并释放了内存。
这可能就足够了:
class Polynomial
{
private:
std::vector<int> coefficients;
public:
inline int getLength() const { return coefficients.size(); };
Polynomial(int length): coefficients(length, 0) {};
Polynomial operator*(const Polynomial& p); //you are not modifying p, thus const ref can work
extern friend istream& operator>>(istream &is, Polynomial &p);
extern friend ostream& operator<<(ostream &os, Polynomial &p);
};
或者,您可以使用阵列解决方案,并使用所有必要的东西实现它:
class Polynomial
{
public:
Polynomial(int length);
~Polynomial();
Polynomial(const Polynomial& other);
friend void swap(Polynomial& first, Polynomial& second) // nothrow
Polynomial& operator=(Polynomial other)
{
swap(*this, other);
return *this;
}
int getLength();
Polynomial operator*(const Polynomial& p); //you are not modifying p, thus const ref can work
extern friend istream& operator>>(istream &is, Polynomial &p);
extern friend ostream& operator<<(ostream &os, const Polynomial &p);
};
修改:您还需要inline int operator[](int n) const { return coefficients[n];}
。