Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have the following code :
class FLOAT
{
float *num;
public:
FLOAT(){}
FLOAT(float f)
{
num = new float(f);
}
FLOAT operator +(FLOAT& obj)
{
FLOAT temp;
temp.num = new float;
temp.num = *num + obj.getF();
return temp;
}
float getF(){ return *num; }
void showF(){ cout << "num : "<< *num << endl; }
};
It is showing an error.
My question is, how do I access that float *num data member using class object?
There are a lot of mistakes in your class. It is simply not setup correctly.
The class's default constructor is not allocating the float at all.
the class is not following the Rule of 3/5/0. It is missing a destructor to free the float, a copy constructor and copy assignment operator to make safe copies of the float, and in C++11 and later, it is missing a move constructor and move assignment operator to safely move the float between objects.
your operator+ is not dereferencing the pointer when assigning a new value to the float.
Try this instead:
class FLOAT
{
float *num;
public:
FLOAT(float f = 0) : num(new float(f)) {}
FLOAT(const FLOAT &src) : num(new float(*(src.num))) {}
// in C++11 and later...
FLOAT(FLOAT &&src) : num(src.num) { src.num = nullptr; }
// alternatively:
// FLOAT(FLOAT &&src) : num(nullptr) { std::swap(num, src.num); }
~FLOAT() { delete num; }
FLOAT& operator=(const FLOAT &rhs)
{
*num = *(rhs.num);
return *this;
}
// in C++11 and later...
FLOAT& operator=(FLOAT &&rhs)
{
std::swap(num, rhs.num);
return *this;
}
FLOAT operator+(const FLOAT& rhs)
{
FLOAT temp;
*(temp.num) = *num + rhs.getF();
return temp;
// or simply:
// return *num + rhs.getF();
}
float getF() const { return *num; }
void showF() { cout << "num : " << *num << endl; }
};
That being said, there is no good reason to dynamically allocate the float at all (except maybe as a learning experience). Let the compiler handle the memory management for you:
class FLOAT
{
float num;
public:
FLOAT(float f = 0) : num(f) {}
FLOAT(const FLOAT &src) : num(src.num) {}
FLOAT& operator=(const FLOAT &rhs)
{
num = rhs.num;
return *this;
}
FLOAT operator+(const FLOAT& rhs)
{
FLOAT temp;
temp.num = num + rhs.getF();
return temp;
// or simply:
// return num + rhs.getF();
}
float getF() const { return num; }
void showF() { cout << "num : " << num << endl; }
};
Which can then be simplified a little by letting the compiler implicitly define the copy constructor and copy assignment operator for you:
class FLOAT
{
float num;
public:
FLOAT(float f = 0) : num(f) {}
FLOAT operator+(const FLOAT& rhs)
{
FLOAT temp;
temp.num = num + rhs.getF();
return temp;
// or simply:
// return num + rhs.getF();
}
float getF() const { return num; }
void showF() { cout << "num : " << num << endl; }
};
When you assign bellow statement :
temp.num = *num + obj.getF();
Actually you assign a float number to a float pointer!
So, use of bellow :
(*temp.num) = (*num) + obj.getF();
Instead of :
temp.num = *num + obj.getF();
Related
I'm using visual studio.
I have 3 class.
It's ok when I try to print Rectangle ABCD, but when i push ABCD into Array [rectangle] A and try to print ABCD again, the "wntdll.pdb not loaded" appear and i continue, it's "triggers breakpoint error!!" at delete in ~Rectangle()
I know it's something up to the pointer in class Rectangle but can't firgure out.
`int main(){
Array<Rectangle>A;
Rectangle a;
cout << a; //It's oke
A.PushBack(a); // problem here
cout<<a;
}`
class Point
{
private:
float _x;
float _y;
public:
float GetX() { return _x; }
float GetY() { return _y; }
public:
Point();
Point(float, float);
Point(const Point&);
~Point() {};
public:
string ToString() const;
public:
friend istream& operator>>(istream&, Point*);
friend ostream& operator<<(ostream&, const Point&);
};
Point::Point() {
_x = 1;
_y = 1;
}
Point::Point(float x, float y) {
_x = x;
_y = y;
}
Point::Point(const Point& a) {
_x = a._x;
_y = a._y;
}
string Point::ToString() const{
stringstream out;
out << "( " << _x << "," << _y << " )";
return out.str();
}
istream& operator>>(istream& in, Point* a) {
cout << "Nhap x: ";
in >> a->_x;
cout << "Nhap y: ";
in >> a->_y;
return in;
}
ostream& operator<<(ostream& out, const Point& a)
{
out << a.ToString();
return out;
}
```
class Rectangle
{
private:
Point* _topleft;
Point* _botright;
public:
void Set_topleft(Point tl) { _topleft = &tl; }
Point Get_topleft() { return *_topleft; }
void Set_botright(Point br) { _botright = &br; }
Point Get_botright() { return *_botright; }
public:
Rectangle();
Rectangle(Point*, Point*);
~Rectangle();
public:
string ToString() const;
public:
friend istream& operator>>(istream&, Rectangle&);
friend ostream& operator<<(ostream&, const Rectangle&);
};
Rectangle::Rectangle()
{
_topleft = new Point(0, 2);
_botright = new Point(3, 0);
}
Rectangle::Rectangle(Point* a, Point* b)
{
_topleft = new Point(*a);
_botright = new Point(*b);
}
Rectangle::~Rectangle()
{
delete _topleft;
delete _botright;
}
string Rectangle::ToString() const
{
stringstream out;
out << "A" << *_topleft << "+" << "D" << *_botright;
return out.str();
}
istream& operator>>(istream& in, Rectangle& a)
{
std::cout << "A( x,y ): ";
in >> a._topleft;
std::cout << "D( x,y ): ";
in >> a._botright;
return in;
}
ostream& operator<<(ostream& out, const Rectangle& a)
{
out << a.ToString();
return out;
}
```
template<class T>
class Array
{
private:
T* _a;
int _len;
public:
Array();
~Array();
public:
int length() { return _len; }
void PushBack(T);
T GetAt(int);
};
template<class T>
Array<T>::Array() {
_a = new T[128];
_len = 0;
}
template<class T>
Array<T>::~Array() {
delete[] _a;
_len = 0;
}
template<class T>
void Array<T>::PushBack(T value) {
if (_len >= 128)
{
std::cout << "Array is over size, which is 128\n";
return;
}
_a[_len] = value;
_len++;
}
template<class T>
T Array<T>::GetAt(int pos) {
return _a[pos];
}
```
The problem in your code is that when you PushBack the Rectangle object a into the array, you create copy of this object. This means that you just copy pointers _topleft and _botright. So in this part of code, you have 2 objects with the same pointers, so you're trying to delete twice the same part of memory.
To fix this you need to define own copy constructor, which will create new pointers in the new object.
Remember also to define own move constructors or make it disable for your class.
Rectangle(const Rectangle &other)
{
if(other._topleft)
_topleft= new Point(*other._topleft);
else
_topleft = nullptr;
if(other._botright)
_botright= new Point(*other._botright);
else
_topleft = nullptr;
}
The next problem is because of definition of void Array<T>::PushBack(T value). Please change it to the void Array<T>::PushBack(const T& value).
Also, try Rectangle(Rectangle&& o) = delete;
I have the following class which is called CoordinatesList. It contains a dynamic array of Coordinates, where each coordinate has 3 integers; x,y, and z.
In the class CoordinatesList, I have two different member operator=, I am slightly confused about what is the difference between them?
Will it work the same if I inherited the class coordinates in the class CoordinatesList
class Coordinates {//this is a complete class, do not modify it.
public:
Coordinates() {
x = new int; y = new int; z = new int;
*x = *z = *y = 0;
}
Coordinates(int _x, int _y, int _z) {
x = new int; y = new int; z = new int;
*x = _x;
*z = _y;
*y = _z;
}
Coordinates(const Coordinates& rhs) { // copy constructor
x = new int; y = new int; z = new int;
*x = *(rhs.x);
*y = *(rhs.y);
*z = *(rhs.z);
}
~Coordinates() {
delete x; delete y; delete z;
}
void operator=(const Coordinates& rhs) {//simplified operator=
*x = *(rhs.x);
*y = *(rhs.y);
*z = *(rhs.z);
}
int getx() const { return *x; }
int gety() const { return *y; }
int getz() const { return *z; }
void setx(int _x) { *x = _x; }
void sety(int _y) { *y = _y; }
void setz(int _z) { *z = _z; }
friend ostream& operator<< (ostream& out, const Coordinates& rhs) {
out << "[" << *(rhs.x) << "," << *(rhs.y) << "," << *(rhs.z) << "]" << endl;
return out;
}
private:
int *x, *y, *z;
}; //--------------------------------------------------------------
class CoordinatesList {
public:
/*CoordinatesList & operator=(const CoordinatesList &rhs)
{
if (size != rhs.size)
{
delete[] list;
size = rhs.size;
list = new Coordinates[size];
}
for (int i = 0; i < size; i++)
{
list[i].Coordinates::operator=(rhs.list[i]);
}
return *this;
} */
CoordinatesList operator=(const CoordinatesList & rhs)
{
//check if sizes are differernt
if (size != rhs.size)
{
delete[] list; //this calls ~coordinates
size = rhs.size;
list = new Coordinates[size];
}
//copy content
for (int i = 0; i < size; i++) {
//list[i] = rhs.list[i];
//will work as operator= is defined for Coordinates
list[i].setx(rhs.list[i].getx());
list[i].sety(rhs.list[i].gety());
list[i].setz(rhs.list[i].getz());
}
return *this;
}
private:
Coordinates * list;
int size;
};
using CL = CoordinatesList; to save on typing.
The difference is that one returns a reference, one returns a copy.
The idiomatic way is to return a reference to *this, so use this one:
CL& operator=(const CL& rhs){/*...*/ return *this;}
Note that having both versions defined will result in a compiler error because functions cannot differ only by their return values.
Usage of operator=:
CL a = CL(<args>);// (1)
CL b,c;
b = a; // (2)
b.operator=(a); //(3)
c = b = a; // (4)
c.operator=(b.operator=(a)); // (5)
(1) Does not call any CL::operator= but a constructor CL::CL(<args>). An object is being created, so a constructor must be called no matter the equal sign.
(2) Is only syntactic sugar for (3). Calls CL::operator= and discards any returned value.
(4) Again, its only syntactic sugar for (5). First the right operator= is evaluated and the returned value is passed to the left operator= as its argument. In this case having operator= returning a copy will indeed make a copy. That's the reason why the second option is preferred as it does not incur this additional and unneeded cost. Also this should be a good explanation for why the function returns anything at all, if it returned void then this syntax would not be possible.
I am learning constructors and Destructors in c++; Help me grasp my mistakes even if they are silly...
HERE is a code I have written to perform addition using classes in c++; This creates two summands of datatype num and employs the constructor sum() to perform sum of the two numbers; However when everything was goin' alright, I stumbled upon creating a copy constructor for num , (Although not necessary but still for practice)... without the dynamic object of the class sum it is not possible to run the code anyway(without removing the copy constructor)... Help me improve my code and my mistakes in the code below; Also I wanna know how to make use of the copy constructor in this program; the problem being that in the destructor the delete operation is being performed multiple times on the same piece of memory (I suppose)
Here's my Code
#include<iostream>
#include<new>
using namespace std;
class num
{
public:
int *a;
num(int x)
{
try
{
a=new int;
}
catch(bad_alloc xa)
{
cout<<"1";
exit(1);
}
*a=x;
}
num(){ }
num(const num &ob)
{
try
{
a=new int;
}
catch(bad_alloc xa)
{
cout<<"1''";
exit(2);
}
*a=*(ob.a);
}
~num()
{
cout<<"Destruct!!!";
delete a;
}
};
class sum:public num
{
public:
int add;
sum(num n1,num n2)
{
add=*(n1.a)+*(n2.a);
}
int getsum()
{
return add;
}
};
int main()
{
num x=58;
num y=82;
sum *s=new sum(x,y);
cout<<s->getsum();
delete s;
return 0;
}
I may miss something - didn't use new/delete for too long, but tried to correct all what I noticed.
P.S. always use smart pointers.
#include <iostream>
#include <exception>
#include <new>
using namespace std;
int* allocate(const char* err_msg, int exit_code)
{
int* a = nullptr;
try
{
a = new int;
}
catch (bad_alloc&)
{
cout << err_msg << endl;
exit(exit_code);
}
return a;
}
class num
{
int* a = nullptr; // always should be initialized here
public:
num() noexcept : a(nullptr) // or here
{}
/*explicit*/ num(int x) : a(allocate("1", 1))
{
*a = x;
}
num(const num& ob) : a(allocate("1''", 2))
{
*a = *(ob.a);
}
// rule of zero/three/five
// default copy assignment will copy pointer and one int will be leaked and one will be deleted twice
num& operator =(const num& ob)
{
if (&ob == this)
{
return *this;
}
*a = *(ob.a);
return *this;
}
~num()
{
cout << "Destruct!!!";
delete a;
a = nullptr; // usefull for debug
}
int value() const
{
if (a == nullptr)
{
throw runtime_error("a == nullptr");
}
return *a;
}
};
class sum
{
int add = 0;
public:
sum(const num& n1, const num& n2)
{
add = n1.value() + n2.value();
}
int getsum() const
{
return add;
}
};
int main()
{
const num x = 58;
const num y = 82;
const sum* s = new sum(x, y);
cout << s->getsum() << endl;
delete s;
return 0;
}
First, I'm not good at english and also first time in StackOverflow, but I try to explain about my code's problem.
I was asked to make my own Vector(similar thing) from my professer, and there's a problem in fuction which returns a reference to the element at the requested position in the vector container. If the requested position is out of range, it should output some messages and terminate the program.
I should make this to Operator overloading, and this is my code.
double operator [](int n, const MyDoubleVector& _mV)//The arror come out at this line.
{
if(n > num)//'num' is private reference in class to count array. it typed int.
{
return 0;
}
return &_mV.data[n];//'data' is private reference in class. It declare like 'double *data = new double [num];'
}
I saw that sometimes 'friend' solve this, but when I put 'friend' in this line, it said me like "operator[] must be a member function."
Finally, Ihave no idea how to do. Would you please help me?
You need to implement the overload of operator[] as a member function of your class MyDoubleVector.
Here's the definition :
double & MyDoubleVector::operator[](int index);
operator [] must be defined as a member of the class.
example:
#include <iostream>
#include <cstdlib>
#include <algorithm>
struct MyDoubleVector
{
MyDoubleVector()
{}
MyDoubleVector(MyDoubleVector const& other)
{
// very naiive copy constructor
if (other.data)
{
std::for_each(other.data, other.data + other.num, [&](double val)
{
this->push(val);
});
}
}
MyDoubleVector& operator=(MyDoubleVector const& other)
{
auto temp = other; // invoke copy constructor
std::swap(num, temp.num);
std::swap(capacity, temp.capacity);
std::swap(data, temp.data);
return *this;
}
~MyDoubleVector()
{
delete [] data;
}
double& operator [](int n);
/** either define the method inline like this...
{
if(n > num)
{
std::cerr << "MyDoubleVector::operator[]: index " << n << " out of range" << std::endl;
std::exit(100);
}
return data[n];
}
**/
void push(double val)
{
if (num == capacity)
{
more();
}
data[num++] = val;
}
private:
void more()
{
if (!data)
{
data = new double [10];
capacity = 16;
}
else
{
auto newcapacity = capacity * 2;
auto newdata = new double [newcapacity];
std::copy(data, data + capacity, newdata);
std::swap(data, newdata);
capacity = newcapacity;
delete [] newdata;
}
}
int num = 0;
int capacity = 0;
double* data = nullptr;
};
/** ...
** or out of line like this
**/
double& MyDoubleVector::operator [](int n)
{
if(n > num)
{
std::cerr << "MyDoubleVector::operator[]: index " << n << " out of range" << std::endl;
std::exit(100);
}
return data[n];
}
int main()
{
MyDoubleVector v;
v.push(10.0);
v[1];
}
Hi I am trying to debug a program and one of the errors I am receiving is 'Missing Initialization for Constructor'. Do I need to declare the vector upfront and how do I initialize it?
#include <iostream>
#include <vector>
using namespace std;
class Point {
private:
double x;
double y;
public:
double get_x() { return x; }
double get_y() { return y; }
bool set_x(double arg) {
x = arg;
return true;
}
bool set_y(double arg) {
y = arg;
return true;
}
Point() : x(0), y(0) {}
Point(double argx, double argy) : x(argx), y(argy) {
}
};
class Vector {
private:
Point A;
Point B;
public:
Point get_A() { return A; }
Point get_B() { return B; }
Vector(const Point &arg1, const Point &arg2) : A(arg1), B(arg2)
{
//this->A = arg1;
//this->B = arg2;
//A = arg1;
//B = arg2;
}
void set_A(const Point &arg) {
A = arg;
}
void set_B(const Point &arg) {
B = arg;
}
static Vector add_vector(const Vector &vector1, const Vector &vector2) {
if (&vector1.B != &vector2.A) {
//Error 1 Vector V1 No Matching constructor for initialization for 'vector'
Vector rval;
return rval;
}
Point one = vector1.A;
Point two = vector2.B;
Vector newvector(one, two);
//newvector.A = one;
//newvector.B = two;
return newvector;
}
Vector add_vector(const Vector &arg) {
// Type of this? Vector *; These three lines are equivalent:
//Point one = this->A;
//Point one = (*this).A;
Point one = A;
Point two = arg.B;
Vector newvector(one, two);
//newvector.A = one;
//newvector.B = two;
return newvector;
}
};
int main() {
//Error 2 Vector v No Matching constructor for initialization for 'vector'
Vector v;
cout << "(" << v.get_A().get_x() << ", " << v.get_A().get_y() << "),\n" <<
"(" << v.get_B().get_x() << ", " << v.get_B().get_y() << ")\n";
//Error 3 Vector V1 No Matching constructor for initialization for 'vector'
Vector v1(1,2), v2(2,3);
Vector res = Vector::add_vector(v1, v2);
cout << "(" << res.get_A().get_x() << ", " << res.get_A().get_y() << "),\n" <<
"(" << res.get_B().get_x() << ", " << res.get_B().get_y() << ")\n";
}
Your issue here is your class is not default constructable.
Vector rval;
Requires a default constructor. Since you provided a user defined constructor the compiler will no longer make a default constructor for you.
To create a default constructor for Vector you can use
Vector() = default;
If you have C++11 or higher or you can use
Vector() {}
For pre C++11.
I am not sure what you are trying to do with
Vector v1(1,2)
Vector needs two Points and each Point needs 2 values.