I implementing vector. so i test operators, but operator+ is not working correctly.
hereis header MyDoubleVector.h
class MyDoubleVector {
public:
MyDoubleVector();
MyDoubleVector(size_t init_capacity);
MyDoubleVector(const MyDoubleVector& v);
~MyDoubleVector();
MyDoubleVector& operator=(const MyDoubleVector& v); //for deep copy
bool operator==(const MyDoubleVector& v); //binary
MyDoubleVector& operator+=(const MyDoubleVector& add);
MyDoubleVector operator[](int index); //return reference to data that requested index
MyDoubleVector operator+(const MyDoubleVector& rhs); //binary
MyDoubleVector operator-(const MyDoubleVector& rhs); //binary
MyDoubleVector operator*(const MyDoubleVector& rhs); //binary
MyDoubleVector operator-(); //unary
MyDoubleVector operator()(); //unary
void pop_back();
void push_back(double x);
size_t capacity() const;
size_t size() const;
void reserve(size_t n);
bool empty() const;
void clear();
void print_info();
private:
double *data;
size_t capa;
size_t used;
};
and here is implement code "MyDoubleVector.cpp"
MyDoubleVector MyDoubleVector::operator+(const MyDoubleVector &rhs) { //binary
//pre : same size,
//poset : return sum,
if (capa != rhs.capa) {
exit(1);
}
MyDoubleVector tmp(capa);
for (size_t i = 0; i < capa; i++) {
tmp.data[i] = data[i] + rhs.data[i];
}
return tmp;
};
and main code is
int i = 0;
MyDoubleVector v1(3);
for (i = 0; i < 4; i++) {
v1.push_back(i);
}
cout << "v1" << endl;
v1.print_info();
MyDoubleVector v2(3);
for (i = 0; i < 4; i++) {
v2.push_back(i * 10);
}
cout << "v2" << endl;
v2.print_info();
cout << "(v1+v2)" << endl;
(v1+v2).print_info();
output is
v1
0 1 2 3
used : 4, capa : 4
v2
0 10 20 30
used : 4, capa : 4
(v1+v2)
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66
used : 0, capa : 4
i think retruned tmp is freed when print_info() function executed.
how print vector correctly?
You aren't setting the used of the return vector. Without seeing the rest of the implementation of the class, I guess you can change to:
MyDoubleVector MyDoubleVector::operator+(const MyDoubleVector &rhs) { //binary
//pre : same size,
//poset : return sum,
if (capa != rhs.capa) {
exit(1);
}
MyDoubleVector tmp(capa);
for (size_t i = 0; i < capa; i++) {
tmp.push_back(data[i] + rhs.data[i]);
}
return tmp;
};
Related
I want to make "set" function. This function changes the values of a2 from "set(int x, int y)" to "y"
#include <iostream>
using namespace std;
class IntArray {
private:
int* m_data;
int m_len;
public:
IntArray(int = 0, int = 0);
~IntArray();
void print(void);
IntArray(const IntArray& copy); // copy Constructor
void set(int x , int y) {
int temp = x;
x = y;
y = temp;//!!
}
};
IntArray::IntArray(int size, int init) {
if (size <= 0) {
m_data = nullptr; m_len = 0;
}
else {
m_data = new int[size];
m_len = size;
for (int idx = 0; idx < m_len; ++idx)
*(m_data + idx) = init;
}
}
IntArray::~IntArray() {
delete[]m_data;
}
void IntArray::print(void) {
for (int idx = 0; idx < m_len; ++idx)
cout << *(m_data + idx) << ' ';
cout << std::endl;
}
int main() {
cout << "a1: ";
IntArray a1{ 10, 100 };
a1.print();
cout << "a2: ";
IntArray a2{ a1 };// 10~100
a2.set(3, 999);
a2.set(9, 123);
a2.print();
return 0;
}
Excepted
a1: 100 100 100 100 100 100 100 100 100 100
a2: 100 100 100 999 100 100 100 100 100 123
Here's what you need.
let's fix up your declaration and introduce two new helper methods, alloc and copyFromOther.
class IntArray {
private:
int* m_data;
int m_len;
void alloc(int len);
void copyFromOther(const IntArray& copy);
public:
IntArray();
IntArray(const IntArray& copy);
~IntArray();
IntArray& operator=(const IntArray& copy);
void print();
void set(int index, int value);
};
Then the helper methods are for quick allocations and copy. Notice that I didn't special case length == 0. That's because it's perfectly fine to say, new int[0]. It will allocate a pointer of zero length. You can change this if you want to force a null pointer when length is zero. Also be aware that copy constructors need to be able to handle "copying to yourself". That is, if you say:
IntArray arr(10, 20);
arr.set(5,5);
arr = arr;
As weird as the above looks, it's the source of a lot of bugs when a copy constructor doesn't handle that case. That's covered below.
So now the implementation
void IntArray::alloc(int len) {
delete [] m_data; // erase what we had before
m_data = new int[len]; // you could say m_data = len ? new int[len] : nullptr
m_len = len;
}
void IntArray::copyFromOther(const IntArray& copy) {
// special case - allow for "copying to ourselves" by doing nothing
// if we didn't handle this, the alloc function would delete the pointer
if (copy.m_data == m_data) {
return;
}
alloc(copy.m_len);
for (int idx = 0; idx < m_len; ++idx)
m_data[idx] = copy.m_data[idx];
}
}
Then the implementation
IntArray::IntArray() : m_data(nullptr) {
alloc(0);
}
IntArray::IntArray(const IntArray& copy) m_data(nullptr), m_len(0) {
copyFromOther(copy);
}
IntArray& IntArray::operator=(const IntArray& copy) {
copyFromOther(copy);
return *this;
}
And let's fix your set method as you had asked about it in a separate question:
void IntArray::set(int index, int value) {
if ((index >= 0) && (index < m_len)) {
m_data[index] = value;
}
}
Your destructor and print methods are fine as you have them. print doesn't need to have an explicit void parameter.
this is the header of a class that I have been designing for an assignment. I have included constructors, a destructors, as well as overloaded operators. Could you give me a hint how to properly define the constructors in a class using c++ 20 most recent features in an efficient way.
#ifndef VECTOR_DOUBLE_H
#define VECTOR_DOUBLE_H
#include <memory>
#include <vector>
class vector_double {
public:
vector_double(int size);
vector_double(std::initializer_list<double> lst);
vector_double(const double* array, int size);
vector_double(const vector_doubler& other);
vector_doubleoperator=(const vector_double& other);
// because I use a managed pointer I don't need a destructor
~vector_double() noexcept = default;
void set(int index, double val);
double& get(int index);
const double& get(int index) const;
int size() const;
void reset(double val);
void fill_from(std::initializer_list<double> lst);
void fill_from(const double* array, int size);
int copy_to(std::vector<double>& vec) const;
double& operator[](int index);
const double& operator[](int index) const;
operator double() const;
vector_double add(const vector_double& other) const;
vector_doubleadd(double number) const;
vector_doublemul_by(double number) const;
void resize(int size);
friend std::ostream& operator<<(std::ostream& out, const vector_double& vec);
private:
std::unique_ptr<double[]> m_array;
int m_size;
};
inline std::ostream& operator<<(std::ostream& out, const vector_double& vec){
if (vec.m_size == 0){
out << "{ }";
}
else{
auto first = true;
out << '{';
for (int i=0; i < vec.m_size; ++i){
if (!first)
out << ", ";
else
first = !first;
out << vec.m_array[i];
}
out << '}';
}
return out;
}
#endif //VECTOR_DOUBLE_H
This example definition may help, I tried sticking to C++20 features:
#include <cmath>
#include "vector_double.h"
vector_double::vector_double(int size):
m_array{ new double[size] },
m_size{size}
{}
vector_double::vector_double(std::initializer_list<double> lst): //Constructor that takes an init list
vector_double(lst.size())
{
std::copy(lst.begin(), lst.end(), m_array.get());
}
vector_double::vector_double(const double* array, int size): //Constructor that takes array and size
vector_double(size)
{
// std::copy(array, array + size, m_array.get());
std::copy(&array[0], &array[size], m_array.get());
}
vector_double::vector_double(const vector_double& other): //Copy Constructor
vector_double(other.m_size)
{
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
vector_double& vector_double::operator=(const vector_double& other) {
if (this != &other) {
if (m_size != other.m_size) {
auto* array = new double[other.m_size];
m_array.reset(array);
m_size = other.m_size;
}
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
return *this;
}
void vector_double::set(int index, double val) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
m_array[index] = val;
}
double& vector_double::get(int index) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
const double& vector_double::get(int index) const {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
int vector_double::size() const {
return m_size;
}
void vector_double::reset(double val) {
for (int i=0; i<m_size; ++i){
m_array[i] = val;
}
}
void vector_double::fill_from(std::initializer_list<double> lst) {
int size = std::min((int)lst.size(), m_size);
std::copy(lst.begin(), lst.begin() + size, &m_array[0]);
}
void vector_double::fill_from(const double* array, int size) {
size = std::min(size, m_size);
for (int i = 0; i < size; ++i) {
m_array[i] = array[i];
}
}
int vector_double::copy_to(std::vector<double>& vec) const {
for (int i = 0; i < m_size; ++i) {
vec.push_back(m_array[i]);
}
return m_size;
}
double& vector_double::operator[](int index) {
return m_array[index];
}
const double& vector_double::operator[](int index) const { //Overloading "[]" operator
return m_array[index];
}
vector_double::operator double() const {
double sum = 0.0;
for (int i = 0; i < m_size; ++i) {
sum += m_array[i] * m_array[i];
}
return std::sqrt(sum);
}
vector_double vector_double::add(const vector_double& other) const {
if (m_size != other.m_size)
throw std::logic_error("size mismatch");
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += other[i];
}
return copy;
}
vector_double vector_double::add(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += number;
}
return copy;
}
vector_double vector_double::mul_by(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] *= number;
}
return copy;
}
void vector_double::resize(int size) {
if (size != m_size){
auto array = new double[size] {0,};
auto common = std::min(size,m_size);
for (int i = 0; i < common; ++i) {
array[i] = m_array[i];
}
m_array.reset(array);
m_size = size;
}
}
I'm writing program to work with different types of matrices such sparse matrices and other.
Now I have complete class of one matrix type called DOK and decided that I need an abstract class Matrix to be inherited in other child matrices and I will be able to apply all virtual operations
with different classes. So I made
Base class:
#include "Triplet.h"
#include <iostream>
using namespace std;
template<typename T>
class Matrix{
public:
virtual Matrix<T>& operator*=(const Matrix<T>& B) = 0;
virtual const Matrix<T>& operator*(const Matrix<T>& B) const = 0;
virtual Matrix<T>& operator-=(const Matrix<T>& B) = 0;
virtual const Matrix<T>& operator-(const Matrix<T>& B) const = 0;
virtual Matrix<T>& operator+=(const Matrix<T>& B) = 0;
virtual const Matrix<T>& operator+(const Matrix<T>& B) const = 0;
virtual T operator()(int i, int j) = 0;
virtual T operator()(int i, int j) const = 0;
[[nodiscard]] virtual int getSizeN() const = 0;
[[nodiscard]] virtual int getSizeM() const = 0;
[[maybe_unused]] virtual void insert(const Triplet<T> &Element) = 0;
[[maybe_unused]] virtual void print() const = 0;
};
template<typename T>
ostream& operator<<(ostream &os, const Matrix<T>& matrix) {
matrix.print();
return os;
}
Triplet.h is struct
template<typename T>
struct Triplet{
int i;
int j;
T b;
};
Tabs is
template<typename T>
T Tabs(T num){
if(num<T(0)) return -num;
else return num;
}
And child class DOK:
#include "Matrix.h"
#include <map>
#include <iostream>
#include <vector>
#include <iterator>
#include "Triplet.h"
//#include "Solver.h"
#include "Tabs.h"
#include "cmath"
#include "gnuplot-iostream.h"
#include <utility>
using namespace std;
template<typename T>
T tolerance = T(1e-19);
template<typename T>
class DOK: public Matrix<T>{
private:
/*
* Dictionary of Keys, pair<int, int> is coordinates of non-zero elements,
* next int is value
*/
int size_n;
int size_m;
map<pair<int, int>, T> dict;
// int count;
public:
DOK(vector<Triplet<T>> &matrix, int n, int m){
this->resize(n, m);
this->fill(matrix);
}
DOK(int n, int m){
this->resize(n, m);
}
~DOK() = default;
void fill(vector<Triplet<T>> &matrix){
//this->count=matrix.size();
//cout<<"Input your coordinates with value in format \"i j val\" "<<endl;
for(int k = 0; k < matrix.size(); k++){
this->insert(matrix[k]);
}
}
void insert(const Triplet<T> &Element) override{
if(Element.i >= this->size_n){
this->size_n = Element.i+1;
}
if(Element.j >= this->size_m){
this->size_m = Element.j+1;
}
pair<int, int> coordinates = {Element.i, Element.j};
this->dict.insert(pair(coordinates, Element.b));
}
void resize(int n, int m){
this->size_n=n;
this->size_m=m;
}
void print() const override {
cout<<endl;
for(int i = 0; i < this->size_n; i++){
for(int j = 0; j < this->size_m; j++){
if(this->dict.find({i, j})!= this->dict.cend()) cout<< fixed << setprecision(18)<<this->dict.find(pair(i, j))->second<<" "; else cout<<0<<" ";
}
cout<<endl;
}
}
void clearZeros(){
for(auto i = this->dict.begin(); i!=this->dict.end();){
if(Tabs(i->second) <= tolerance<T>){
i = this->dict.erase(i);
} else{
i++;
}
}
}
[[nodiscard]] int getSizeN() const override{
return this->size_n;
}
[[nodiscard]] int getSizeM() const override{
return this->size_m;
}
void clearZeros(){
for(auto i = this->dict.begin(); i!=this->dict.end();){
if(Tabs(i->second) <= tolerance<T>){
i = this->dict.erase(i);
} else{
i++;
}
}
}
DOK<T>& operator+=(const Matrix<T> &matrix) override {
try{
if(this->getSizeN() != matrix.getSizeN() || this->getSizeM() != matrix.getSizeM()) throw 1;
for(int i = 0; i < this->getSizeN(); i++) {
for (int j = 0; j < this->getSizeM(); j++) {
T c = this->operator()(i, j) + matrix(i, j);
if(Tabs(c) > tolerance<T>) this->insert({i, j, c}); else this->dict.erase({i, j});
}
}
return *this;
}
catch (int a) {
cout<<"Sizes of Matrices are different."<<endl;
}
}
const DOK<T>& operator+(const Matrix<T>& matrix) const override {
DOK<T> t = *this;
return move(t+=matrix);
}
DOK<T>& operator-=(const Matrix<T>& matrix) override {
try{
if(this->getSizeN() != matrix.getSizeN() || this->getSizeM() != matrix.getSizeM()) throw 1;
for(int i = 0; i < this->getSizeN(); i++) {
for (int j = 0; j < this->getSizeM(); j++) {
T c = this->operator()(i, j) - matrix(i, j);
if(Tabs(c) > tolerance<T>) this->insert({i, j, c}); else this->dict.erase({i, j});
}
}
return *this;
}
catch (int a) {
cout<<"Sizes of Matrices are different."<<endl;
}
}
const DOK<T>& operator-(const Matrix<T> &matrix) const override {
DOK<T> t = *this;
return move(t-=matrix);
}
DOK<T>& operator*=(const Matrix<T> &matrix) override {
try {
if(this->getSizeN() != matrix.getSizeN()) throw 1;
DOK<T> M = DOK(this->getSizeN(), matrix.getSizeM());
for (int i = 0; i < this->getSizeN(); i++) {
for (int j = 0; j < matrix.getSizeM(); j++) {
T a=0;
for(int k = 0; k<this->getSizeM(); k++){
if(this->operator()(i, k) != 0 && matrix(k, j) != 0){
a+=this->operator()(i, k)*matrix(k,j);
//cout<<a<<endl;
}
}
Triplet<T> m = {i, j, a};
M.insert(m);
}
}
this->clearZeros();
*this=M;
return *this;
}
catch (int a) {
cout<<"Wrong sizes of matrices to multiplication"<<endl;
}
}
const DOK<T>& operator*(const Matrix<T>& matrix) const override{
DOK<T> t = *this;
return t*=matrix;
}
T operator()(int row, int col) override{
if(this->dict.find({row, col}) != dict.end()) return this->dict.find({row, col})->second;
else return T(0);
}
T operator()(int row, int col) const override{
if(this->dict.find({row, col}) != dict.end()) return this->dict.find({row, col})->second;
else return T(0);
}
};
But I faced a problem that now I can't create DOK object because Matrix is an abstract class.
So if I did
DOK<double> Q = DOK<double>(...)
cout<<Q*Q;
and it was working
but now I can't do like this and one possible variant is to dereference pointer
Matrix<double>* Q = new DOK<double>(...);
cout<<(*Q) * (*Q);
How can I fix it without rewriting code from references to pointers?
I'm a beginner when it comes to C++ and have recently ran in to a very frustrating problem with my small program where I'm practicing operator overloading and templates.
I've created a template-class called SortedVector that can store instances of various types.
using namespace std;
template <class T, int size> class SortedVector {
public:
SortedVector();
bool add(const T& v);
T& median();
void sortArray();
void removeLarge(const T& v);
void print(ostream &os);
void compexch(T& x, T& y);
void sortArray(T* data, int s);
private:
T arr[size];
int arraySize;
};
template <class T, int size> SortedVector<T, size>::SortedVector() {
arraySize = 0;
for (int i = 0; i < size; i++) {
arr[i] = T();
}
}
template <class T, int size> bool SortedVector<T, size>::add(const T& v) {
if (arraySize > size - 1) {
cout << "Array is full!" << endl;
return false;
} else {
arr[arraySize] = v;
arraySize++;
sortArray(arr, arraySize);
}
return true;
}
template <class T, int size> void SortedVector<T, size>::sortArray(T* data, int s) {
for (int i = 0; i < s - 1; i++) {
for (int j = i + 1; j < s; j++) {
compexch(data[i], data[j]);
}
}
}
template <class T, int size > T & SortedVector<T, size>::median() {
}
template <class T, int size> void SortedVector<T, size>::removeLarge(const T & v) {
}
template <class T, int size> void SortedVector<T, size>::print(ostream & os) {
for (int i = 0; i < arraySize; i++) {
cout << arr[i] << endl;
}
}
template <class T, int size> inline void SortedVector<T, size>::compexch(T& x, T& y) {
if (y < x) {
T temp = x;
x = y;
y = temp;
}
}
It can store ints succesfully and it can also store Polygons (a custom made class created in a earlier assignment).
Polygon.h:
class Polygon {
public:
Polygon(Vertex vertexArray[], int size);
Polygon() : vertices(0), arraySize(0) {}
~Polygon() {delete[] vertices;}
void add(Vertex v);
float area();
int minx();
int maxx();
int miny();
int maxy();
int numVertices() const {return arraySize;}
friend ostream &operator << (ostream &output, const Polygon& polygon);
friend bool operator > (Polygon polygon1, Polygon polygon2);
friend bool operator < (Polygon polygon1, Polygon polygon2);
private:
int arraySize;
Vertex * vertices;
};
Polygon.cpp declaration:
using namespace std;
void Polygon::add(Vertex v) {
arraySize++;
Vertex * tempVertexes = new Vertex[arraySize];
for (int i = 0; i < arraySize; i++) {
if (i == arraySize - 1) {
tempVertexes[i] = v;
} else {
tempVertexes[i] = vertices[i];
}
}
delete [] vertices;
vertices = tempVertexes;
}
Polygon::Polygon(Vertex vertexArray[], int size) {
arraySize = size;
vertices = new Vertex[size];
for (int i = 0; i < size; i++) {
vertices[i] = vertexArray[i];
}
}
float Polygon::area() {
float area = 0.0f;
for (int i = 0; i < arraySize - 1; ++i) {
area += (vertices[i].getXposition() * vertices[i + 1].getYposition()) - (vertices[i + 1].getXposition() * vertices[i].getYposition());
}
area += (vertices[0].getYposition() * vertices[arraySize - 1].getXposition()) - (vertices[arraySize - 1].getYposition() * vertices[0].getXposition());
area = abs(area) *0.5;
return area;
}
ostream& operator<<(ostream &output, const Polygon& polygon) { //Kolla denna!
output << "{";
for (int i = 0; i < polygon.numVertices(); i++) {
output << "(" << polygon.vertices[i].getXposition() << "," << polygon.vertices[i].getYposition() << ")";
}
output << "}";
return output;
}
bool operator>(Polygon polygon1, Polygon polygon2) {
if (polygon1.area() > polygon2.area()) {
return true;
} else {
return false;
}
}
bool operator<(Polygon polygon1, Polygon polygon2) {
if (polygon1.area() < polygon2.area()) {
return true;
} else {
return false;
}
}
template <class T> inline void compexch(T& x, T& y) {
if (y < x) {
T temp = x;
x = y;
y = temp;
}
}
The code for the Vertex class:
class Vertex {
public:
Vertex() : y(0), x(0) {}
Vertex(int xPosition, int yPosition) : x(xPosition), y(yPosition) {}
~Vertex() {}
int getXposition() const {return x;}
int getYposition() const {return y;}
private:
int x;
int y;
};
The problem however is that the overloaded <<-operator seems print out the wrong values from the main-method:
int main() {
SortedVector<Polygon, 10> polygons;
SortedVector<int, 6> ints;
ints.add(3);
ints.add(1);
ints.add(6);
Vertex varr[10];
varr[0] = Vertex(0, 0);
varr[1] = Vertex(10, 0);
varr[2] = Vertex(5, 2);
varr[3] = Vertex(5, 5);
polygons.add(Polygon(varr, 4));
cout << "varr area:" << (Polygon(varr, 4)).area() << endl;
varr[0] = Vertex(0, 0);
varr[1] = Vertex(25, 8);
varr[2] = Vertex(10, 23);
polygons.add(Polygon(varr, 3));
cout << "var area (1):" << (Polygon(varr, 3)).area() << endl;
varr[0] = Vertex(0, 0);
varr[1] = Vertex(5, 0);
varr[2] = Vertex(5, 3);
varr[3] = Vertex(4, 8);
varr[4] = Vertex(2, 10);
polygons.add(Polygon(varr, 5));
cout << "var area (2):" << (Polygon(varr, 5)).area() << endl;
polygons.print(cout);
ints.print(cout);
cout << "MEDIAN: " << ints.median() << endl;
cout << "MEDIAN: " << polygons.median() << endl;
return 0;
}
The code that is printed is:
var area (1):247.5
var area (2):33.5
{(6029504,0)(5,0)(5,3)}
{(6029504,0)(5,0)(5,3)(4,8)}
{(6029504,0)(5,0)(5,3)(4,8)(2,10)}
1
3
6
MEDIAN: 1
MEDIAN: {(6029504,0)(5,0)(5,3)}
Firstly, the method prints out the same polygon but with varying sizes. Secondly, it points out the wrong getXPosition() for the first object in the array. Everything else (that is implemented, like the ints and the area) is correct tho. Why is this? Am I missing something important here or am I just completely of with my program?
If theres any more code needed I am happy to provide it.
Regards
Given the code you posted, the issues are clear as to what's wrong.
You're passing Polygon's by value here:
friend bool operator > (Polygon polygon1, Polygon polygon2);
friend bool operator < (Polygon polygon1, Polygon polygon2);
and you're copying and assigning values here in: compexch:
if (y < x) {
T temp = x; // copy constructor
x = y; // assignment
y = temp; // assigment
}
This means that copies will be made, and your Polygon class cannot be copied safely. You will have memory leaks and bugs when calling either of these functions.
You should implement the appropriate copy constructor and assignment operator, whose signatures are:
Polygon(const Polygon& rhs); // copy constructor
Polygon& operator=(const Polygon& rhs); // assignment operator
Both of these functions should be implemented. Please see the Rule of 3 for this information.
However, for operator < and operator >, you should pass references, not values to these functions:
friend bool operator > (Polygon& polygon1, Polygon& polygon2);
friend bool operator < (Polygon& polygon1, Polygon& polygon2);
Then the copy constructor and assignment operator are not brought into play, since the parameter type is a reference.
Let's try to implement the copy / assignment functions anyway, for completeness:
For example, the copy constructor can be implemented like this:
Polygon::Polygon(const Polygon& rhs) : vertices(new int[rhs.arraySize]),
arraySize(rhs.arraySize)
{
for (int i = 0; i < arraySize; ++i)
vertices[i] = rhs.vertices[i];
}
Then for the assignment operator, using the copy / swap idiom:
Polygon& operator=(const Polygon& rhs)
{
Polygon temp(rhs);
std::swap(temp.arraySize, arraySize);
std::swap(temp.vertices, vertices);
return *this;
}
Once you've implemented these function, plus the destructor that calls delete[], you should no longer have an issue with copying the objects.
Other issues:
In addition, you really should only overload < and ==, initially with their "full" implementation, and write the other relational operators with respect to these two operators.
Right now, you're making the classic mistake of writing one operator (operator >), and then trying to turn the logic "inside-out" when implementing operator <. What if the logic for operator > were more complex, and it took yeoman's work to figure out what is the "opposite of <"?
If you implemented ==, then operator > just becomes:
return !(polygon1 < polygon2) && !(polygon == polygon2); // <-- this can be further improved by implementing operator !=
Okay this program is to let some user enter an amount of numbers and it will output them in a straight line with commas in between. I have got every other code to work except for overloading the output operator.
Here's the header file:
#ifndef LISTTYPE_H_INCLUDED
#define LISTTYPE_H_INCLUDED
#include <iostream>
class ListType {
public:
ListType(size_t=10);
virtual ~ListType();
virtual bool insert(int)=0;
virtual bool erase();
virtual bool erase(int)=0;
virtual bool find(int) const=0;
size_t size() const;
bool empty() const;
bool full() const;
friend std::ostream& operator << (std::ostream&, const ListType&);
protected:
int *items;
size_t capacity;
size_t count;
};
Here's the cpp file:
#include "ListType.h"
ListType::ListType (size_t a) {
capacity = a;
count = 0;
items = new int [capacity];
}
ListType::~ListType() {
delete [] items;
}
bool ListType::erase() {
count = 0;
return 0;
}
size_t ListType::size() const {
return (count);
}
bool ListType::empty() const {
return (count == 0);
}
bool ListType::full() const {
return (count == capacity);
}
std::ostream& operator << (std::ostream& out, const ListType& list1) {
int a = 0;
out << list1[a] << ", " ;
return out;
}
Any help will be deeply appreciated.
You can use a function similar to this in your class:
void ListType::output(std::ostream& out) const {
for (int i = 0; i < count; i++) {
if (i > 0) { // No comma for first element
out << ", ";
}
out << items[i];
}
}
The overloaded << method of ostream can then be rewritten to this to call the output function:
std::ostream& operator << (std::ostream& out, const ListType& my_list) {
my_list.output(out);
return out;
}