当我在运算符*函数中返回对象temp时,它主要不会被复制到p3中。
操作符*函数中的cout语句返回正确的值,但是main中的p3只有垃圾。
另外,我在main的返回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;
}发布于 2015-03-14 11:10:46
如果使用正确的标志调用编译器,则此代码不得编译。没有适用于默认标志的C++编译器!
例如,让我们以VisualC++ 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)'现在,让我们看看如果我们删除禁用Microsoft扩展的/Za标志会发生什么:
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++。即使您可以让VisualC++编译代码,也不会有任何好处。
转让经营者的正确签名是:
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和操作符重载的最佳实践。
发布于 2015-03-14 10:24:51
假设它会编译。
您没有复制构造函数,这不是一个好主意。如果实现析构函数,则可能需要赋值-复制-交换-移动函数。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];}。
https://stackoverflow.com/questions/29047717
复制相似问题